likes
comments
collection
share

TypeScript类型体操--IsUnion

作者站长头像
站长
· 阅读数 18

大家好,我是苏先生,一名热爱钻研、乐于分享的前端工程师,跟大家分享一句我很喜欢的话:人活着,其实就是一种心态,你若觉得快乐,幸福便无处不在

github与好文

前言

前边九篇文章我们一共实现了36个工具类型,按照本专栏的规划,还差63个...

本节我们继续学习一个新的工具类型

TypeScript类型体操--IsUnion

提示

代码实现

我们先来分析下联合类型的特性

TypeScript类型体操--IsUnion

联合类型表示的是一组或关系,它的每一个值都是不相等的,或者至少有两个是不相等的

type UnionCase = 'a'|'b'|'c'|'a'|'d'

当我们对一个联合类型构建条件类型时,它会依次进行比较

'a' extends UnionCase ? true : false

对于上述条件语句,实际上相当于

'a' extends 'a' ? true : false
'a' extends 'b' ? true : false
'a' extends 'a' ? true : false
'a' extends 'c' ? true : false
'a' extends 'd' ? true : false

并且TypeScript会依次收集每一次的比较结果并帮我们组合成联合类型返回,故求值后得到的结果如下

type UnionResult = true | false | true | false | false

而UnionResult与true比较得到的是false

TypeScript类型体操--IsUnion

接着,来分析非联合类型的特点

在JavaScript中,任何一个值对自身进行判断得到的一定是真值,类比到TypeScript中也是一样的

type Impl<T> = T extends T ? true : never

而true与true的比较得到的一定是true

则,如果能让Impl工具类型既能返回true又能返回联合类型,就可以对其返回类型与true进行比较,为false就表示联合类型

type IsUnion<T> = Impl<T> extends true ? false : true

故我们来构建分布式条件类型,这是获取联合类型的必要条件。并且还需要能够取到联合类型的key去构建'a' extends UnionCase ? true : false的形式

为此,我们设计一个泛型变量,它作为Impl的第二个参数,并且它是T的副本

type Impl<T,U extends T = T>

既然联合类型时会对T进行拆分,则左侧的U[0]...就是我们要取的key

U[0] extends T[0]
U[0] extends T[1]
U[0] extends T[2]
...
U[2] extends T[0]
U[2] extends T[1]
U[2] extends T[2]

简写后的key如下

U extends T

故,完整代码如下

type Impl<T,U extends T = T> = T extends T ? U extends T ? true : false : never
type IsUnion<T> = Impl<T> extends true ? false : true

使用示例

TypeScript类型体操--IsUnion

TypeScript类型体操--IsUnion

下期预告

Uniq

  • 功能

lodash中数组去重的ts版本

  • 使用示例
type case1 = FindOnceAppearAtArray<[1,1,2,3,4,5,3,1,2,5,1]> // [1,2,4,5,3]

如果本文对您有用,希望能得到您的点赞和收藏

订阅专栏,每周更新1-2篇类型体操,等你哟😎