Mapped typesとは?
あるオブジェクトのプロパティ 名を利用して新しい型を作り出す機能のことです。実現するためにはkeyofやin keyofなどの構文があります。
TypeScriptのType定義の保守性向上のために使えます。
keyofとは?
プロパティ 名を文字列リテラル型のユニオン型として定義することが可能になります。
1 2 3 4 5 6 |
interface Person { name: string; age: number; } type PersonKey = keyof Person; |
上のPersonKeyには「"name" | "age"」というユニオン型が入ります。
in keyof
プロパティ 名に対応するデータ型を一つずつ取り出します。
例えば、以下はPartialのTypeですが、Tで渡したインターフェースを一つずつ取り出して中身のデータの型をそのまま新しくデータ型として再定義しています。
1 2 3 |
type Partial<T> = { [P in keyof T]?: T[P]; }; |
typeof
実際の値を型に変換する構文です。変数に対して使用します。JavaScriptのtypeof演算子(変数の型チェックするやつ)とは全く別物なので注意です。
1 2 3 4 |
const a = { b: 'ああ' } const c: typeof a = { b: 1} // 数値なのでエラーめ |
メリット
通常はinterfaceやtypeなどを作ってから型定義をしますが、すでに定義済みのオブジェクトがある場合はそれをそのまま型に使えるので実装が楽になります。(例えば、パッケージとかで自動生成されるようなコードがあった場合に項目が大量にあったらいちいち手動で型定義するのは大変ですしね。最近だったらgraphqlなどで使えるような気がします。)
keyofとtypeofの併用
1 2 3 4 5 6 7 8 |
const a = { b: 'あ', c: 'い', d: 'う', } let e: keyof typeof a; // 'b' | 'c' | 'd'という型になる。 e = 'b'; |
keyofは変数には使えないのでtypeofを使って一旦変数を型に変換した後にkeyofを使ってあげれば「オブジェクトの変数」から「文字列リテラル型のユニオン型」を生成することが可能です。
実務でも結構よく使っているソースは見るので押さえておきましょう。
この記事へのコメントはありません。