|
在 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 是只读的
来源:https://www.cnblogs.com/zimengxiyu/p/18068993 |