1

keyof 用来返回一个class类型或者interface类型的所有key组成的联合类型。可以看下面的一个例子:

一: 当把keyof用在一般常见的class类型和interface类型上

type Point = { 0: number; height: number };
interface Point2{name: string; age: number}

type KeyOfPoint = keyof Point; // 0 | 'height'
type KeyOfPoint2 = keyof Point2; // 'name' | 'age'

const fn = (key: KeyOfPoint | KeyOfPoint2)=>{}

fn(0) //no error
fn('height') //no error
fn('name') //no error
fn('age') //no error

fn('width') // error: 类型不匹配

在以上的代码里面 :

key: KeyOfPoint | KeyOfPoint2

就相当于:

key: 0 | 'height' | 'name' | 'age'

所以,当我们调用:fn('width')的时候就会报错,因为‘width’不在Point和Point2的key的列表里面。

二: 当把keyof用在index signature的class类型上时

number类型的index signature, 结果为: number

type Arrayish = { [n: number]: unknown };
type A = keyof Arrayish; // type A = number

string类型的index signature,结果为: string | number。这是因为,当我定义string类型的index signature时,我依然可以给number类型的key,因为JavaScript会把对象的number类型的key强制转为string,比如obj[0]和obj['0']是相等的。

type Arrayish = { [n: string]: unknown };
type A = keyof Arrayish; // type A = number | number
const fn = (key: A)=>{}
fn('xxx') // no error
fn(0) // no error

以上是keyof的通常使用场景,也是keyof被设计出来的初衷。但是,假如我们把keyof用到enum, number,string等类型上会得到什么呢?

三: 当把keyof用在number类型的enum上

enum Colors {
    red,
    blue,
    yellow
}
type A = keyof Colors; // "toString" | "toFixed" | "toExponential" | "toPrecision" | "valueOf" | "toLocaleString"

当把keyof用在number类型的enum上时,会得到Number.prototype上所定义的方法的名字(string格式)的联合类型。

四: 当把keyof用在string类型的enum上

enum Colors {
    red = 'red',
    blue = 'blue',
    yellow = 'yellow'
}
type A = keyof Colors; // number | "toString" | "charAt" | "charCodeAt" | "concat" | ...27 more... | "padEnd"

当把keyof用在string类型的enum上时,我们就得到一个由number类型再加上String.prototype上定义的所有的方法的名字组成的一个联合类型。


nanaistaken
583 声望43 粉丝

« 上一篇
null 和undefined