こんにちは、まさにょんです。
今日は、TypeScriptで「配列から型を生成する4-Pattern」について共有します。
今回、共有するのは以下の4つです。
『サバイバルTypeScript』の「配列から型を生成する」で学んだまんまですがoutput大事なので紹介します!
- typeof演算子でArrayの構造を抽出する
- as const & typeof演算子でLiteral型を保有した配列を抽出する
- 特定のLiteral型を抽出する( as const & typeof & [index] )
- すべてのLiteral型を抽出する( as const & typeof & [number] = Union型 )
それでは、1つずつ見て行きましょう。
目次
1. typeof-演算子で配列から型を抽出する
// 1. 配列から型を生成する => typeof-演算子を使用する。
const robotamaDevelopList = ["robotama1", "robotama2", "robotama3", "robotama4", "robotama5"];
type robotamaType = typeof robotamaDevelopList;
// < 作成された型 > type robotamaType = string[]
TypeScriptのtypeof-演算子で配列の構造(型)を抽出することができます。
この場合の型の抽出結果は、抽象的な string[] になっています。
2. as const & typeof-演算子でLiteral型を保有した配列を抽出する
// 2. 配列からリテラル型の型配列を作成する => as const & typeof を使用する => 定数値として値を取得する。
const robotamaDevelopList2 = ["robotama1", "robotama2", "robotama3", "robotama4", "robotama5"] as const;
type robotamaType2 = typeof robotamaDevelopList2;
// < 作成された型 >
const robotamaDevelopList2: readonly ["robotama1", "robotama2", "robotama3", "robotama4", "robotama5"]
as constで配列を型的に定数化(readonlyに)して、その後にtypeof-演算子で型を抽出すると、Literal型を保有した配列を抽出できます。
as const を使用すると、配列をreadonlyにする・定数値として扱うという宣言になります。
よって、抽象的なstring[] から 具体的で定まった Literal型を保有した配列を抽出できることになります。
3. 特定のLiteral型を抽出する( as const & typeof & [index] )
// 3. 特定のリテラル型が欲しい場合
const robotamaDevelopList3 = ["robotama1", "robotama2", "robotama3", "robotama4", "robotama5"] as const;
type robotamaType3 = typeof robotamaDevelopList3[2];
// < 作成された型 > type robotamaType3 = "robotama3"
特定のLiteral型を抽出したい場合は、as const & typeof-演算子の後にブラケット記法で欲しいLiteral型のindex番号を指定します。
そうすることで、指定したLiteral型を取得することができます。
4. すべてのLiteral型を抽出する( as const & typeof & [number] = Union型 )
// 4. すべてのリテラル型が欲しい場合
const robotamaDevelopList4 = ["robotama1", "robotama2", "robotama3", "robotama4", "robotama5"] as const;
type robotamaType4 = typeof robotamaDevelopList4[number];
/*
< 作成された型 >
type robotamaType4 = "robotama1" | "robotama2" | "robotama3" | "robotama4" | "robotama5"
配列は、number型のインデックスに要素を代入しているオブジェクトなので、
[number] を使うことで、Array[number]に紐づくvalueのリテラル型を取得できます。
*/
すべてのLiteral型を抽出したい場合は、先ほどの考え方から発展してブラケット記法で渡すものを工夫すればいいのです。
配列はnumber型のインデックスに要素を代入しているオブジェクトなのでこのリテラル型のインデックスの代わりにnumberを使うことによって、希望のユニオン型を取得できます。
引用元:『サバイバルTypeScript』配列から型を生成する
この通り、Arrayの[number]をtypeofすると、すべてのLiteral型をUnion型で取得できるわけです。
Sample-Code-まとめ
// < 配列から型を生成したい-Sample-Code >
// 1. 配列から型を生成する => typeof-演算子を使用する。
const robotamaDevelopList = ["robotama1", "robotama2", "robotama3", "robotama4", "robotama5"];
type robotamaType = typeof robotamaDevelopList;
// < 作成された型 > type robotamaType = string[]
// 2. 配列からリテラル型の型配列を作成する => as const & typeof を使用する => 定数値として値を取得する。
const robotamaDevelopList2 = ["robotama1", "robotama2", "robotama3", "robotama4", "robotama5"] as const;
type robotamaType2 = typeof robotamaDevelopList2;
// < 作成された型 > const robotamaDevelopList2: readonly ["robotama1", "robotama2", "robotama3", "robotama4", "robotama5"]
// 3. 特定のリテラル型が欲しい場合
const robotamaDevelopList3 = ["robotama1", "robotama2", "robotama3", "robotama4", "robotama5"] as const;
type robotamaType3 = typeof robotamaDevelopList3[2];
// < 作成された型 > type robotamaType3 = "robotama3"
// 4. すべてのリテラル型が欲しい場合
const robotamaDevelopList4 = ["robotama1", "robotama2", "robotama3", "robotama4", "robotama5"] as const;
type robotamaType4 = typeof robotamaDevelopList4[number];
/*
< 作成された型 >
type robotamaType4 = "robotama1" | "robotama2" | "robotama3" | "robotama4" | "robotama5"
配列は、number型のインデックスに要素を代入しているオブジェクトなので、
[number] を使うことで、Array[number]に紐づくvalueのリテラル型を取得できます。
*/
TypeScript書籍
参考・引用
1. 配列から型を生成する