TypeScriptのkeyof typeof解説
TypeScriptで「keyof typeof」の意味を解説
「keyof typeof」の役割
TypeScriptにおいて、「keyof typeof」は、ある変数またはオブジェクトの型からそのプロパティ名を取得するための演算子です。
具体的な使い方
interface Person {
name: string;
age: number;
}
const person: Person = {
name: "Alice",
age: 30
};
type PersonKeys = keyof typeof person; // type PersonKeys = "name" | "age"
上記の例では、Person
インターフェースを定義し、その型に基づいてperson
オブジェクトを作成しています。そして、keyof typeof person
を用いて、person
オブジェクトのプロパティ名である"name"
と"age"
を取得しています。
- 柔軟性
異なるオブジェクトや変数の型に対して、同じ方法でプロパティ名を取得できます。 - コードの簡潔さ
冗長なプロパティ名の列挙を避けることができます。 - 型安全
TypeScriptの型システムを活用することで、コンパイル時にプロパティ名の誤りを検出できます。
「keyof typeof」とユニオン型の組み合わせ
複数の型を組み合わせたユニオン型に対して、「keyof typeof」を使用することもできます。
type Animal = { name: string; };
type Bird = { name: string; canFly: boolean; };
const animal: Animal | Bird = { name: "Sparrow", canFly: true };
type AnimalOrBirdKeys = keyof typeof animal; // type AnimalOrBirdKeys = "name" | "canFly"
例1: シンプルなオブジェクトのプロパティ名取得
interface Person {
name: string;
age: number;
}
const person: Person = {
name: "Alice",
age: 30
};
type PersonKeys = keyof typeof person; // type PersonKeys = "name" | "age"
// PersonKeys型を使用してプロパティにアクセス
console.log(person[PersonKeys.name]); // 出力: Alice
例2: ユニオン型に対するプロパティ名取得
type Animal = { name: string; };
type Bird = { name: string; canFly: boolean; };
const animal: Animal | Bird = { name: "Sparrow", canFly: true };
type AnimalOrBirdKeys = keyof typeof animal; // type AnimalOrBirdKeys = "name" | "canFly"
// AnimalOrBirdKeys型を使用してプロパティにアクセス
if ("canFly" in animal) {
console.log(animal.canFly); // 出力: true
}
例3: ジェネリック型を用いた汎用的なプロパティ名取得
function getPropertyNames<T>(obj: T): (keyof T)[] {
return Object.keys(obj) as (keyof T)[];
}
const person = { name: "Bob", age: 25 };
const propertyNames = getPropertyNames(person);
console.log(propertyNames); // 出力: ["name", "age"]
例4: マッピング型と組み合わせたプロパティ名の変更
interface Person {
firstName: string;
lastName: string;
}
type PersonWithUpperCase = {
[K in keyof Person]: Uppercase<Person[K]>;
};
const person: Person = { firstName: "John", lastName: "Doe" };
const personWithUpperCase: PersonWithUpperCase = {
firstName: "JOHN",
lastName: "DOE"
};
Object.keys()
- 欠点
型安全がやや弱く、プロパティ名が文字列として扱われるため、コンパイル時にエラーが検出されない場合がある。 - 利点
シンプルで直感的。 - 基本的な使い方
interface Person { name: string; age: number; } const person: Person = { name: "Alice", age: 30 }; const propertyNames: (keyof typeof person)[] = Object.keys(person);
マッピング型
- 欠点
複雑なマッピングが必要な場合、コードが冗長になる可能性がある。 - 利点
型安全が向上し、プロパティ名の型チェックが可能。 - 基本的な使い方
interface Person { name: string; age: number; } type PersonKeys = keyof typeof person; type PersonWithUpperCase = { [K in PersonKeys]: Uppercase<Person[K]>; };
Extract型
- 欠点
複数のプロパティ名を抽出する場合、コードが冗長になる可能性がある。 - 利点
特定のプロパティ名のみを抽出できる。
選択基準
- 特定のプロパティ抽出
Extract
型が適している。 - シンプルさ
Object.keys()
が最もシンプル。 - 型安全
マッピング型が最も型安全。
typescript typeof union-types