前两天在复习typescript
的时候,发现了一个特别有意思的类型工具Equal
,它能比较各种字面值
是否相等,同时也能比较类型
是否完全相同
:
实际上么,在typescript
中,能有这种能力的也只有extends
了,所以我一开始觉得是这样实现的:
type Equal<X,Y> = X extends Y ? true : false
不过很显然失败了,因为extends
存在分发
,所以并不能非常严格
的区分类型,比方说{ a:string; }
和{ a:string; b:string; }
如果用刚才的实现也是true
:
也很好理解嘛,{ a:string; b:string; }
继承自{ a:string; }
,所以条件成立。但是如何绕过这个分发
呢,那用函数类型
+ 约束类型
,就行了。所以我们改造一下Equal
:
type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false
测试一下各种情况:
附上原issue
:
[Feature request]type level equal operator · Issue #27024 · microsoft/TypeScript (github.com)