Skip to content

TS 中的类型操作符 ​

2023-10-10 16:19:06

keyof ​

keyof 是一个单目运算符,接受一个对象类型作为参数,会返回该对象的所有键名组成的联合类型。

ts
type MyObj = {
  foo: number
  bar: string
}

type Keys = keyof MyObj // 'foo'|'bar'

这里有一个函数 用于传入一个对象和属性 返回属性值

ts
function prop(obj, key) {
  return obj[key]
}

我们正常写类型时是像这样

ts
function prop(obj: { [p: string]: any }, key: string): any {
  return obj[key]
}

上面的类型声明有两个问题,一是无法表示参数 key 与参数 obj 之间的关系,二是返回值类型只能写成 any

而有了 keyof 我们可以准确写出类型

ts
function prop<Obj, K extends keyof Obj>(obj: Obj, key: K): Obj[K] {
  return obj[key]
}

in ​

在 js 中 in 操作符被用来判断一个属性是否在一个对象中

而在 ts 中 in 操作符被用来遍历联合类型的每一个成员类型

ts
type U = 'a' | 'b' | 'c'

type Foo = {
  [Prop in U]: number
}
// 上面得到的Foo是等同于下面的
type Foo = {
  a: number
  b: number
  c: number
}

infer ​

infer 关键字用来定义泛型里面推断出来的类型参数,而不是外部传入的类型参数,通常跟条件运算符一起使用,用在 extends 关键字后面的父类型之中

ts
type Flatten<Type> = Type extends Array<infer Item> ? Item : Type

// string
type A = Flatten<string[]>

// number
type B = Flatten<number>

看这个例子,定义了一个类型 Flatten,接受一个泛型,通过 infer 来推断出 Item,如果传入的 Type 是数组类型,那么会返回数组中的元素的类型,如果不是数组会返回传入的类型

所以下边 A 先传入一个字符串数组类型 string[],判断是数组类型,返回了推断出的数组中元素的类型,所以 A 为 string 类型

而 B 传入的是一个 number 类型,不是数组,所以会返回本身

Released under the MIT License.