Programmingフルスタック開発者

インデックスアクセス型(型アクセス、T[K]のように)はどのように機能しますか?構造体の変更によるエラーを回避する方法や、複雑なオブジェクトにおける役割について教えてください。

Hintsage AIアシスタントで面接を突破

答え

インデックスアクセス型(または型アクセス)は、オブジェクトの特定のプロパティの型や任意のキーをT[K]の構文を使用して参照することを可能にする強力なツールです。柔軟かつ型安全な抽象化を作成するための強力な手段です。

例:
type Person = { name: string; age: number; }; type NameType = Person['name']; // string type AgeOrName = Person['age' | 'name']; // number | string

ジェネリック型や関数の作成に使用されます:

function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; // 戻り値の型が正しい } const user = { email: 'a@a.ru', id: 1 }; let id = getProperty(user, 'id'); // id: number

用途:

  • 型コンストラクタの作成(例えば、複雑なネストされた構造からキーを使用して値の型を引き出すこと)。
  • 関連する型の構築(Record, Pickなど)

ニュアンス:

  • 元の型(Person)を変更すると、インデックスアクセスの結果も変わり、バインディングに予期せぬ影響を与える可能性があります!
  • TSは、キーが存在しない場合の状況を捕捉しません:Person['salary'] — コンパイル時エラー。

トリック質問

質問: type Foo = {a: number, b: string}["a" | "b" | "c"]の式はどのような型になりますか?

回答: この例はコンパイルエラーを引き起こします。なぜなら、'c'はアクセスしている型のキーではないからです。TypeScriptは以下のエラーを表示します:

Type '"c"' does not satisfy the constraint '"a" | "b"'.

知識不足による実際のエラーの例。


物語

プロジェクトでは、型に基づいて動的にフォームが生成されていました。基本型に新しいフィールドを追加した後、キーによるインデックスがある場所を更新せずに、いくつかのプロパティがフォームに入らない結果となり、型レベルでは完全なマッピングが期待されていました。エラーは開発段階ではなく、ランタイムでのみ発生しました。


物語

データのバリデーションライブラリでは、タイプを介したインデックスアクセスが使用されましたが、コードの移行中に、オブジェクトから親に1つのキーを移動しました。古いインデックス型はコンパイルエラーを引き起こしましたが、キャッシュのためCIで再ビルドするまでエラーは発生せず、ステージングで数週間生きていました。


物語

インデックスアクセス型を使用すると、明示的に列挙されていないキーにもアクセスできると誤って考え、動的プロパティの自動テストの生成に誤りが生じました。その結果、コンパイラがこれらのケースを無効として処理したため、テストは可能なシナリオの一部をカバーできませんでした。