类型体操的一些特殊情况说明
类型体操的实现的一些常用技巧
- extends
- infer
- 递归
- 模板字符串
- number
- typeof
严格全等equal的实现说明
参考:IsEqual演进史
我是先写的下面的内容再看的参考,看完参考后后发现下面写了一些些废话,根本没get到要点
要做类型体操还是参考这个库吧: 类型体操leetcode
相关的测试用例要写全,比如我下面的一段自我理解,完全解释不了 type A9 = IsEqual<any, string> 为啥得到了false
已废弃
ts
// 先给出实现
type Equal<X, Y> = <T>() => (T extends X ? 1 : 2) extends <T>() => (T extends Y ? 1 : 2) ? true : false
type isEqual = Equal<string, string> // true
type isEqual2 = Equal<string, number> // false
type isEqual3 = Equal<string, any> // false
语句拆分
- <T>() => (T extends X ? 1 : 2)
- <T>() => (T extends Y ? 1 : 2)
- A extends B ? true : false
我的理解
当extends的左右A和B是这种带有泛型的函数定义时, 直接取函数返回值再继续(这样好理解,实际按这样理解,结果也是对的,至于tsc是具体怎么检查这个类型定义的,那得看源码了吧) 那为什么写的时候不直接写后面的返回值部分,还要写成这种函数类型?因为要加入泛型T啊,要不然T从哪来
- false的情况 如果T extends X得到1,又如果X, Y不相等,那么T extends Y就得到2,最终1 extends 2 得到false
- true的情况 如果T extends X得到1,又如果X, Y相等,那么T extends Y就得到1,最终1 extends 1 得到true
一种形式理解
ts
type X = string
type Y = any
declare let varX: <T>() => (T extends X ? 1 : 2)
declare let varY: <T>() => (T extends Y ? 1 : 2)
let x = varX<any>() // typeof x 得到1 | 2,类似于前面所说取函数返回值
let y = varY<any>() // typeof y 得到2,类似于前面所说取函数返回值
type yT1 = any extends string ? 1 : 2 // 1 | 2
type yT2 = any extends any ? 1 : 2 // 1 | 2
type yt3 = 1 | 2 extends 1 | 2 ? true : false // false
// 把y赋值给x, 报错,因为x类型为1 | 2, y类型为2,通过变量赋值的形式验证了类型X和Y不相等
x = y
// 这个和最前面的equal很相似了吧
type isEqual = typeof x extends typeof y ? true : false // 得到true, 为啥string和any相等了?怎么解释
另一种形式理解
ts
// isEqual的简易形式
type X = string
type Y = number
type A<T> = T extends X ? 1 : 2
type B<T> = T extends Y ? 1 : 2
type AString = A<string> // 1
type BString = B<string> // 2
// A于B的泛型参数要保持一致
type isEqual = A<string> extends B<string> ? true : false // false 说明 X不等于Y
// 复杂写法
// 约等于A<string> 约等于B<string>
// <T>() => (T extends X ? 1 : 2 <T>() => (T extends Y ? 1 : 2)
type isEqual<X, Y> = <T>() => (T extends X ? 1 : 2) extends <T>() => (T extends Y ? 1 : 2) ? true : false
type isEqual2 = isEqual<X, Y> // false
type isEqual3 = isEqual<string, string> // true