之前写了一篇 TS 一些工具泛型的使用及其实现
, 但是一直没怎么使用 TS,回首看文章,发现自己都看不懂了。
期间内 TS 也有一些变化,所以这一篇将会承接上篇文章,分析解读更多的工具泛型,主要来自 utility-types项目的源码。
阅读本流水账需要对 TS 中的以下东西有所了解
- extends
- keyof
- in
- infer
- &
- |
- ?
- -?
- +?
- never
- unkown
- any
- readonly
- void
正文
ArrayElement
提取数组成员类型,
一个思路是 用 extends 限制数组类型, 然后用数组 key 类型为 number 的特性取出其属性类型
1 | type ArrayElement<T extends readonly unknown[]> = T[number]; |
第二种写法的核心思路就是用 infer 来隐射 数组的属性类型
1 | type ArrayElement<A> = A extends readonly (infer T)[] ? T : never |
Exclude & Extract vs. Diff & Filter
TS 内置类型定义涵盖了 Exclude & Extract, 但是在它的官方文档又给出了另外的名字
1 | type Diff<T, U> = T extends U ? never : T; |
就类型定义的代码而言,Exclude === Diff, Extract === Filter,蜜汁操作
NonNullable
从类型 T 中排除 null 和 undefined
1 | type NonNullable<T> = Exclude<T, null | undefined> |
Parameters
拿到函数的参数类型,不定参数的组织形式就是一个数组,参考 ArrayElement
的第二种写法,利用infer
去取到类型
1 | type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never |
ConstructorParameters
要拿到构造函数参数的类型,参考 Parameters
,加上 new
即可
1 | type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never |
InstanceType
获取实例类型,跟 Parameters
和 ConstructorParameters
差不多,不过这次不 infer
参数了,而是 infer
函数返回数据
1 | type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : never |