# 战斗基-联合类型的分发特性

TODO: 待进一步完善

# 普遍认为的分发特性

# 实际类似的分发特性

{ [P in keyof T]: T[P] }

分布特性这一点在 ts 中还是比较常见的,其实个人感觉理解成分发更合适。官网是这么介绍的:

ts 官方文档 (opens new window)

实际还是直接上实例:

type Case1 = 'x' extends 'x' ? 1 : 2; // 1

type Case2 = 'x' | 'y' extends 'x' ? 1 : 2; // 2

type Case3<T> = T extends 'x' ? 1 : 2;

type R3 = Case3<'x' | 'y'>; // 1 | 2

若 extends 前面的类型是泛型,且泛型传入的是联合类型时,则会依次判断该联合类型的所有子类型是否可分配给 extends 后面的类型。而返回的结果就是 分别分配后的值组成的联合类型,对应到 case3, 就是 1 | 2。

如果 extends 前面不是泛型,就直接判断前者是否可以分配给后者,所以在上述 case2 结果是 2。

一句话概括,就是 extends 前面的参数为泛型且为联合类型时则会分解联合类型进行判断,然后将最终的结果组成新的联合类型。

不想使用该特性,只需要通过元组包裹即可。

type Case3<T> = [T] extends ['x'] ? 1 : 2;

type R3 = Case3<'x' | 'y'>; // 2

在实际的应用中,笔者个人感觉还有如下的场景使用分发理解更为合适:

type MapObj<T> = {
  [P in keyof T]: P;
};

type FilterBoolean<T> = {
  [P in keyof T]: T[P] extends boolean ? never : T[P];
}[keyof T];

在 MapObj 中,keyof T 是一个联合类型,[P in keyof T],有点类似于对联合类型进行遍历,此处也存在一定的分发的感觉,把原本的联合类型进行了分发成一个一个。

而 FilterBoolean 中,最后一行的 [keyof T],其本质是索引取值 (opens new window),索引是 联合类型时,也会有类似分发的效果,最终输出的也是联合类型,在本例中就是过滤了 boolean 类型(never | 任何类型 = 任何类型)

Last Updated: 2023/5/16 06:00:28