4

次のようなインターフェースがあるとしましょう。

interface Person {
  name: string;
  age: number;
}

Readonly を呼び出して、インターフェースの読み取り専用バージョンを作成したい。

interface PersonReadonly extends Readonly<Person> {}

これは書き込みに相当します

interface PersonReadonly {
  readonly name: string;
  readonly age: number;
}

そのような Readonly ジェネリック インターフェイスを作成できますか、それとも既に作成されていますか?

4

4 に答える 4

3

明確な質問に答えるには:技術的には、まだやりたいことができません。

型マッピングは、Typenot インターフェースを作成します -Readonly<T>を返す組み込みの型マッパーですTypeTypeエイリアスを実装または拡張することはできません。インターフェース/クラスのみです。

したがって:

interface PersonReadonly extends Readonly<Person> {}

型の実装のサポートが完了するまで無効です。

ただし、それはあなたがタイプを通過するのを止めるものではありません。型にユニオンを使用して、より複雑な型を構築することもできます。したがって、次のことができます。

type PersonWithState = Readonly<Person> & { state: string }

let person = <Person>{ name: "John", age: 20 };
let personState = <PersonWithState>{ ...person, state: "online" };

personState.age = "30"; // error;
personState.state = "offline"; // OK.

ただし、クラスを実装したり、インターフェイスを拡張したりすることはできませんPersonWithState-まだ。

于 2016-12-17T17:44:31.843 に答える
3

できるよ:

type PersonReadonly = Readonly<Person>

しかし、それはインターフェースではありません。たとえば、別の場所に新しいメンバーを追加することはできません。

2017 年 5 月からの編集: TS 2.2 (2017 年 2 月) 以降、インターフェイスはタイプから派生できます

于 2016-12-17T18:38:39.427 に答える
2

プレイグラウンドでは、Readonlyタイプが定義されているため、次のことができます。

interface Person {
    name: string;
    age: number;
}

let a: Readonly<Person> = {
    name: "name",
    age: 3
};

a.age = 5; // Error: Cannot assign to 'age' because it is a constant or a read-only property

(遊び場のコード)

タイプが環境で定義されている場合は、単純に追加できます。

type Readonly<T> = {
    readonly [P in keyof T]: T[P];
}

ただし、typescript 2.1 以降が必要です。
持っていない場合は、おそらく typescript のバージョンが 2.1 未満であることを意味します。それ以外の場合はそのまま使用できます。

于 2016-12-17T17:35:32.630 に答える
1

インスタンスのすべてのフィールドを作成するためのジェネリック インターフェイスは、 TypeScript 2.1readonly以降で利用できます。

正確Readonly<T>に呼び出されるため、次のように使用できます。

let person: Readonly<Person> = { name: 'John', age: 30 };
person.age = 31; // gives error

TypeScript 2.1 より前では、一般的な読み取り専用型を実装することはできません。

于 2016-12-17T17:35:05.490 に答える