在 TypeScript 中,keyof
是一个操作符,用于获取某种类型的所有公共键的字面量类型的联合。简而言之,keyof
会创建一个由某个类型的所有属性名组成的联合类型。
如何使用 keyof
假设你有一个接口或类型,你想获取这个类型的所有属性名组成的联合类型,你可以使用 keyof
。
interface Person {
name: string;
age: number;
hasPet: boolean;
}
type PersonKeys = keyof Person;
// PersonKeys 的类型是 'name' | 'age' | 'hasPet'
在上面的例子中,PersonKeys
的类型是 'name' | 'age' | 'hasPet'
,即 name
、age
或 hasPet
中的任意一个字符串。
keyof
的应用场景
keyof
非常有用,尤其是在你需要根据对象的属性来约束值时。例如,你可能想写一个函数,该函数接受一个 Person
对象和 Person
的一个属性名,并返回该属性的值。
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key]; // obj[key] 的类型自动被推断为 T[K]
}
const person: Person = {
name: 'Alice',
age: 25,
hasPet: false,
};
const personName = getProperty(person, 'name'); // 类型是 string
const personAge = getProperty(person, 'age'); // 类型是 number
const personHasPet = getProperty(person, 'hasPet'); // 类型是 boolean
在这个例子中,函数 getProperty
被定义为泛型函数,它使用了两个类型参数:T
和 K
。T
是对象的类型,而 K
是继承自 T
所有属性键的联合类型的一个子类型。这意味着 K
可以是 T
的任何属性键。
使用 keyof
的好处是类型安全。如果你尝试使用不存在的属性名,TypeScript 编译器会给出错误信息:
const personJob = getProperty(person, 'job'); // 错误:类型 '"job"' 的参数不能赋给类型 '"name" | "age" | "hasPet"' 的参数。
keyof
类型查询与索引访问类型(T[K]
)结合使用时非常强大,允许你以类型安全的方式访问属性值,并确保你不会错误地引用一个不存在的属性名。