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只能作用于类型,而不能直接作用于值,再用keyof把对象属性组成了一个联合类型,它包括了顶层属性 "name" 和 "age",以及对象“adress”而无法直接获取嵌套对象里面的“city”和“postalCode”。
获取嵌套里面的类型可以逐层提取
// 1. 先获取 address 的类型 type AddressType = typeof person["address"]; // { city: string; postalCode: string } // 2. 再用 keyof 提取 address 的键 type AddressKeys = keyof AddressType; // "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 是只读的

浙公网安备 33010602011771号