📍

TypeScript Indexed Access Types 公式ドキュメント

に公開

はじめに

TypeScript の Indexed Access Types は、他の型から特定のプロパティを検索するために使用する型です。

この記事では、TypeScript 公式ドキュメントの内容に基づき、Indexed Access Types の基本概念から実践的な使用方法まで、コード例とともに解説します。

Indexed Access Types

別の型の特定のプロパティを検索するために indexed access type を使用できます:

type Person = { age: number; name: string; alive: boolean };
type Age = Person["age"];
//   ^? type Age = number

インデックス型自体も型であるため、ユニオン、keyof、またはその他の型を完全に使用できます:

type I1 = Person["age" | "name"];
//   ^? type I1 = string | number

type I2 = Person[keyof Person];
//   ^? type I2 = string | number | boolean

type AliveOrName = "alive" | "name";
type I3 = Person[AliveOrName];
//   ^? type I3 = string | boolean

存在しないプロパティをインデックスしようとするとエラーが表示されます:

type I1 = Person["alve"];
//              ~~~~~~~
// Property 'alve' does not exist on type 'Person'.

配列のインデックス

任意の型でインデックスすることの別の例は、number を使用して配列の要素の型を取得することです。これを typeof と組み合わせて、配列リテラルの要素型を便利に取得できます:

const MyArray = [
  { name: "Alice", age: 15 },
  { name: "Bob", age: 23 },
  { name: "Eve", age: 38 },
];

type Person = (typeof MyArray)[number];
//   ^? type Person = { name: string; age: number; }

type Age = (typeof MyArray)[number]["age"];
//   ^? type Age = number

// または
type Age2 = Person["age"];
//   ^? type Age2 = number

型のみでのインデックス

インデックス時に使用できるのは型のみです。つまり、const を使用して変数参照を作成することはできません:

const key = "age";
type Age = Person[key];
//              ~~~
// Type 'key' cannot be used as an index type.
// 'key' refers to a value, but is being used as a type here. Did you mean 'typeof key'?

ただし、似たようなスタイルのリファクタリングには型エイリアスを使用できます:

type key = "age";
type Age = Person[key];
//   ^? type Age = number

まとめ

TypeScript の Indexed Access Types を使用することで、既存の型から特定のプロパティの型を取得できます。

公式ドキュメントで紹介されている主要なパターン:

  1. 基本的なプロパティアクセス: Person["age"]
  2. ユニオン型でのアクセス: Person["age" | "name"]
  3. keyof 演算子との組み合わせ: Person[keyof Person]
  4. 配列要素の型取得: MyArray[number]
  5. typeof との組み合わせ: (typeof MyArray)[number]

重要なポイント

  • インデックスアクセスでは型のみ使用可能(値は使用不可)
  • 存在しないプロパティへのアクセスはコンパイルエラー
  • 型エイリアスを使用してリファクタリング可能

この機能により、型定義の重複を避け、既存の型から必要な部分を効率的に抽出できます。

参考リンク

https://www.typescriptlang.org/docs/handbook/2/indexed-access-types.html
https://www.typescriptlang.org/docs/handbook/2/typeof-types.html
https://www.typescriptlang.org/docs/handbook/2/conditional-types.html

Discussion