infer备忘录

infer备忘录

八月 23, 2021 本文共计: 499 字 预计阅读时长: 2分钟

写在前面的话

同志们,好久不见,甚是想念哎!这段时间,小王忙完了工作生活的琐事,之后更新的频率会高一点的。

正文

infertypescript开发中很少用的一个关键字,但是在类型设计中会比较实用,它的主要作用做条件中的类型推导,配合 extends 关键字使用:

举个栗子:

1
2
3
type GetArrayType<T> = T extends (infer U)[] ? U : T;

let a: GetArrayType<number>; // a: number

前置知识

  • 协变

    什么是协变呢?大白话讲就是类型收敛,类型收敛还不够大白话,再大白话一点就是A|B,非AB嘛。这就是协变。收敛了类型可能出现的范围。

  • 逆变

    什么是逆变呢?大白话讲就是类型发散,类型发散也不够大白话,在大白话一点就是A&B,并集嘛,这就是逆变,扩大了可能出现的范围。

需要注意的点是

对象的逆变协变与值的逆变协变截然相反;

举个栗子:

1
2
3
4
5
6
7
8
9
10
11
type A = {
name: string;
}

type B = {
age: number;
}

type C = A | B;

type D = A & B;

其实不难理解,对于C来说,虽然是 |,但是发生了逆变,也就是新的 C 演变为了:

1
2
3
4
type C = {
name?: string;
age?: number;
}

范围更大了,可以是如下四种范围:

  • 范围一:
1
2
3
4
type C = {
name?: string;
age?: number;
}
  • 范围二:
1
2
3
4
type C = {
name: string;
age?: number;
}
  • 范围三:
1
2
3
4
type C = {
name?: string;
age: number;
}
  • 范围四:
1
2
3
4
type C = {
name: string;
age: number;
}

另外一种,对于D来说:

1
2
3
4
type D = {
name: string;
age: number;
}

相比于C而言,缩小了范围,所以也就不难理解下面的类型推导:

1
type E = D extends C ? true : false; // E: true

End

推荐阅读: