TypeScript中的keyof和in

发布时间 2023-07-21 16:11:53作者: 含若飞

keyof使用

keyof操作符接受一个对象类型作为参数,返回该对象属性名组成的字面量联合

type Dog = { name: string; age: number;  };
type D = keyof Dog; //type D = "name" | "age"

可以看到keyof any 返回的是一个联合类型:string | number | symbol,结合前文说到keyof是为了取得对象的key值组成的联合类型,那么key值有可能是什么类型呢?自然就是string | number | symbol。
该关键字一般会和extends关键字结合使用,对对象属性的类型做限定,比如K extends keyof any就代表K的类型一定是keyof any所返回的联合类型的子类,如果输入不符合限定,那么自然也就不能作为对象的属性,类型系统就会报错。
因此,keyof any 表示了对象key值可能的取值类型。这一点在本文之后的一些类型实现中也会用到。

注意点

遇到索引签名时,keyof会直接返回其类型

type Dog = {  [y:number]: number  };
type dog = keyof Dog;  //type dog = number
type Doggy = {  [y:string]: boolean };
type doggy = keyof Doggy; //type doggy = string | number

type Doggy = {  [y:string]: unknown, [x:number]: boolean};
type doggy = keyof Doggy; //type doggy = string | number

可以看到索引类型为string时,keyof 返回的类型是string | number, 这是因为JavaScript的对象属性会默认转换为字符串。

in的使用

in的右侧一般会跟一个联合类型,使用in操作符可以对该联合类型进行迭代。
其作用类似JS中的for...in或者for...of

type Animals = 'pig' | 'cat' | 'dog'
type animals = {
    [key in Animals]: string
}
// type animals = {
//     pig: string; //第一次迭代
//     cat: string; //第二次迭代
//     dog: string; //第三次迭代
// }