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 来限制属性名的合法性,并返回属性对应的值。

keyoftypeof 的结合使用提供了更好的类型安全,因为它们反映了对象的实际结构。

四、与映射类型结合

可以用 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 是只读的
posted @ 2024-03-12 18:36  雪旭  阅读(81)  评论(0编辑  收藏  举报