在 TypeScript 中,keyof 是一个关键字,用于获取某种类型的所有键(key),并返回这些键组成的联合类型(union type)。它可以帮助你在编译时获取对象的属性名,从而实现更类型安全的代码。
假设有一个接口或类型定义:
interface Person {
name: string;
age: number;
gender: string;
}
使用 keyof 可以获取 Person 类型的所有键:
type PersonKeys = keyof Person; // 结果是 "name" | "age" | "gender"
这里 PersonKeys 的类型是联合类型 "name" | "age" | "gender",包含了 Person 接口中所有属性的名称。
- 类型安全的属性访问
-
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const person: Person = {
name: "Alice",
age: 30,
gender: "female"
};
const name = getProperty(person, "name"); // 类型是 string
const age = getProperty(person, "age"); // 类型是 number
// const invalid = getProperty(person, "invalidKey"); // 编译错误,因为"invalidKey"不是Person的键
- 限制参数只能是对象的键
-
function checkProperty<T>(obj: T, key: keyof T): boolean {
return key in obj;
}
3.与映射类型结合使用
keyof 常与映射类型(Mapped Types)一起使用,创建新的类型:
-
type ReadonlyPerson = {
readonly [K in keyof Person]: Person[K];
};
// 等价于:
// {
// readonly name: string;
// readonly age: number;
// readonly gender: string;
// }
-
- 对于对象类型(包括接口),
keyof 返回其属性名组成的联合类型
- 对于数组类型,
keyof 返回 number | "length" | "toString" | ... 等数组的键和方法名
- 对于基本类型(如
string),keyof 返回该类型原型上的属性和方法
- type StringKeys = keyof string; // 结果包含 "length", "charAt", "toUpperCase" 等字符串方法名
-
keyof 的主要作用是:
- 获取某种类型的所有键,形成联合类型
- 在泛型中约束参数必须是对象的有效键
- 与其他 TypeScript 特性(如映射类型)结合,创建更灵活的类型定义
- 提高代码的类型安全性,在编译时捕获错误
通过 keyof,你可以编写出更通用、更安全且更易于维护的 TypeScript 代码。