6.4 keyof型とlookup型
この節で紹介する機能はTypeScriptの中でも比較的高度な部類に入りますが、使いこなせると型情報の再利用性が高まり、非常に強力な武器となります。
6.4.1 lookup型とは
Section titled “6.4.1 lookup型とは”オブジェクト型から、特定のプロパティの型を抽出(参照)する機能です。
- 構文:
T[K](Tはオブジェクト型、Kはプロパティ名の文字列リテラル型など)。 - 挙動: 例えば
Human["age"]と書くと、Human型のageプロパティの型(numberなど)が得られます。 - メリット: オブジェクトの定義(例:
ageがbigintに変更されるなど)が変わっても、lookup型を使っていれば自動的に追従されるため、型情報を重複して書く必要がなくなり(DRY原則)メンテナンス性が向上します。
6.4.2 keyof型とは
Section titled “6.4.2 keyof型とは”オブジェクト型から、そのオブジェクトが持つすべてのプロパティ名を文字列リテラル型のユニオン型として取得する機能です。
- 構文:
keyof T。 - 挙動:
Human型がnameとageプロパティを持つ場合、keyof Humanは"name" | "age"という型になります。 - 値から型を作るテクニック: オブジェクトの変数
objに対して、keyof typeof objとすることで、「その変数が持つキー名のユニオン型」を動的に生成し、引数などをそのオブジェクトの有効なキーのみに制限するパターンがよく使われます。
6.4.3 keyof型とlookup型とジェネリクス
Section titled “6.4.3 keyof型とlookup型とジェネリクス”keyof と lookup 型は、型引数(ジェネリクス)と組み合わせることでさらに真価を発揮します。
- 安全なプロパティ取得:
function get<T, K extends keyof T>(obj: T, key: K): T[K]のような関数を定義できます。 - 制約(extends)の重要性:
K extends keyof Tという制約があることで、TypeScriptは「Kは必ずTのプロパティ名のどれかである」と確信でき、結果としてT[K]という戻り値の型を安全に推論・許可してくれます。
6.4.4 number型もキーになれる?
Section titled “6.4.4 number型もキーになれる?”オブジェクトのキー名が数値(例: 0: string)で定義されている場合、keyof は文字列リテラルだけでなく数値リテラル型のユニオン型(例: 0 | 1)を返すことがあります。
- 未知の型のキー: 一般に、未知の型
Tに対するkeyof Tは、string | number | symbolの部分型として扱われます。 - 文字列に限定したい場合: キーが確実に文字列であることを保証したい場合は、
K extends keyof T & stringのようにインターセクション型を用いて制限を加えるテクニックが有効です。