はじめに
本記事では typeof
や keyof
を組み合わせて型を定義する方法とその注意点について紹介します。
TypeScript では独自の型を定義する方法として、interface
と type
がありますが、本記事では type
を使用します。
型エイリアス
型エイリアスは、既存の型に別名を付けることができる機能です。type
キーワードを使用して、型エイリアスを宣言します。型エイリアスは、コードの可読性を向上させ、複雑な型定義を簡略化するために使用されます。
// 型エイリアスの宣言
type StringOrNull = string | null; // | で繋げてユニオン型を定義
let subtitle_1: StringOrNull = "Foo Bar";
let subtitle_2: StringOrNull = null;
keyof や typeof を組み合わせた型定義
本題である typeof
や keyof
を組み合わせた型定義を紹介します。
typeof キーワード
typeof
キーワードは、変数やオブジェクトの型を取得します。
// user オブジェクトを定義
let user = { id: 10, name: "John Doe", is_verified: true };
// type User = { id: number; name: string; is_verified: boolean} と同義
type User = typeof user;
[]
を使用すると、オブジェクトのプロパティの型を参照することができます。この構文は、インデックスアクセス型(Index Access Type)と呼ばれます。
// type UserId = number と同義
type UserId = User["id"];
// type UserIdAndName = number | string と同義
type UserIdAndName = User["id" | "name"];
keyof キーワード
keyof
キーワードは、オブジェクトのキーのユニオン型を生成します。インデックスアクセス型と組み合わせることもできます。
// keyof と組み合わることも可能です。
// type UserProp = "id" | "name" | "is_verified" と同義
type UserProp = keyof typeof user;
// type UserValues = number | string | boolean と同義
type UserValues = User[UserProp];
// type UserValues = (typeof user)[keyof typeof user];
ただ、const アサーション(as const
) を使用すると、UserValues
は string | number | boolean
ではなく、10 | "John Doe" | true
になることに注意が必要です。
let user = { id: 10, name: "John Doe", is_verified: true } as const;
// type UserValues = `10 | "John Doe" | true` と同義
type UserValues = (typeof user)[keyof typeof user];
// type UserValues = User[UserProp];