TypeScript中的keyof
在 TypeScript 中, keyof
操作符用于获取某种类型的所有键。它返回一个字符串或数字的联合类型,包含对象类型的所有可用键。keyof
主要用于在编译时进行类型检查,以确保你访问的属性是对象实际拥有的键。
一、基本使用
type Person = { name: string; age: number; address: string; }; type PersonKeys = keyof Person; // 'name' | 'age' | 'address' const key: PersonKeys = "name"; // 合法 // const invalidKey: PersonKeys = "nonexistent"; // 不合法,会报错
在 TypeScript 中,typeof
与 keyof
通常一起使用,用于获取对象的属性名(键)的联合类型。这在创建通用函数或操作对象属性时非常有用
const person = { name: "John", age: 30, address: { city: "New York", postalCode: "10001", }, }; //获取键的联合类型 type PersonKeyType = keyof typeof person; //PersonKeyType 的类型是 "name" | "age" | "address"
在上面的例子中,我们先用typeof把对象的所有属性和属性类型都获取到了,再用keyof把对象属性组成了一个联合类型,它包括了顶层属性 "name"
和 "age"
,以及嵌套对象 address
的属性 "city"
和 "postalCode"
。
二、与泛型结合
可以将 keyof
与泛型结合使用。‘’K extends keyof T
‘’是一种用于泛型约束的语法。它的意思是 K
必须是类型 T
的键(属性名称)之一。这个约束确保了在使用泛型函数或类型时,K
的值只能是 T
类型的属性名称,从而提高类型安全性。
// 泛型函数,K 必须是 T 的键之一 function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; } const person: Person = { name: "John", age: 30, address: "123 Main St" }; const name = getProperty(person, "name"); // 正确,类型为 string // const invalid = getProperty(person, "nonexistent"); // 错误,会报错
三、限制对象键
const person = {
name: "John",
age: 30,
address: {
city: "New York",
postalCode: "10001",
},
};
function getProperty(obj: typeof person, key: keyof typeof person) { return obj[key]; } const personName = getProperty(person, "name"); // 类型是 string const personAge = getProperty(person, "age"); // 类型是 number const city = getProperty(person.address, "city"); // 类型是 string
这个函数 getProperty
接受一个对象和一个属性名,利用 keyof typeof
来限制属性名的合法性,并返回属性对应的值。
keyof
与 typeof
的结合使用提供了更好的类型安全,因为它们反映了对象的实际结构。
四、与映射类型结合
可以用 keyof
和映射类型一起使用,创建基于现有类型的新类型。
type ReadOnly<T> = { readonly [K in keyof T]: T[K]; }; type ReadOnlyPerson = ReadOnly<Person>; const readonlyPerson: ReadOnlyPerson = { name: "John", age: 30, address: "123 Main St" }; // readonlyPerson.age = 31; // 错误,会报错,因为 age 是只读的