前两天在复习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)