配列の内部型を「抽出」するTypeScriptで型を宣言する方法はありますか?
例:
コードベースにすでに次のようなものがあるとしましょう。
export interface Cache {
events: Event[],
users: User[]
}
type CacheType = Event[] | User[];
//or maybe:
// type TypeOfProperty = T[keyof T];
// type CacheType = TypeOfProperty<Cache>;
私が欲しいのはこれと同等のものです:
type InnerCacheType = Event | User;
しかし、Cache
またはCacheType
に何かを追加するたびに、手動で再入力する必要はありません。
これはTypescriptで可能ですか?
これはTypeScript2.8以降で可能です。 Unpacked<T>
型は次のように宣言できます。
type Unpacked<T> = T extends (infer U)[] ? U : T;
今、あなたはすることができます
type InnerCacheType = Unpacked<CacheType>; // Event | User
これは、 ドキュメント で指定されたUnpacked
タイプの要約定義です。
TypeScript 2.1以降を使用できると仮定しましょう。そうしないと、探しているものを実現する方法がありません。
また、Cache
インターフェイスのすべてのプロパティが配列になることは当然のことです。そうでない場合、あなたの質問は無意味になるので、私もこの仮定をします。
一般的に、CacheType
は次のように書くことができます
type CacheType = Cache[typeof Cache];
継承されたプロパティを含みます。得られた型はEvent[] | User[]
と同等ですが、そのような共用体型から配列コンポーネントを抽出することは不可能です。
解決策は、マップされたタイプを使用することです。あなたが探しているInnerCacheType
は次のように書くことができます
type InnerCacheType = MappedCacheType[typeof MappedCacheType];
どこ
type MappedCacheType = { [P in keyof Cache]: Cache[P][0]; };
実際、最後のタイプはと同等です
{ events: Event; users: User; }
TypeScriptは元の名前と同じ名前を保持していることに注意してください。
ユースケースを考慮せずに要約すると、配列型T
のコンポーネント型を表現する方法はT[0]
です。
これは、型クエリでも実現できます。すなわち。
type CacheType = Event[] | User[];
type InnerCacheType = CacheType[number]; // Event | User