我要检查2种类型是否相同。我期望
export type AreSame<T, U, R> = T extends U ? U extends T ? R : never : never;
可以正常工作,但实际上fails在工会上使用:
type A = AreSame<1, 1, Object> // Object
type B = AreSame<1, 2, Object> // never
type C = AreSame<1, number, Object> // never
type D = AreSame<1, 1 | 2, Object> // Object - why???
type E = AreSame<1 | 2, 1 | 3, Object> // Object - why???
type F = AreSame<1 | 2, 1 | 2, Object> // Object
我该如何解决?
答案 0 :(得分:2)
我只是在这里猜测,但是如果我们认为联合类似于逻辑或,那将是有道理的。
让我尝试对问题采取的步骤进行伪编码。
1 extends (1|2) ? (1|2) extends 1 ? Object : never : never // becomes ->
(1 extends 1 || 1 extends 2) ? (1 extends 1 || 2 extends 1) ? : Object : never : never
我会考虑检查打字稿代码以检查其工作原理。
编辑:为解决此问题,我在打字稿存储库中找到了this github issue
最好的解决方案是:
export type Equals<X, Y> =
(<T>() => T extends X ? 1 : 2) extends
(<T>() => T extends Y ? 1 : 2) ? true : false;
也许您可以根据自己的情况进行调整?希望能有所帮助:)
答案 1 :(得分:2)
您的条件类型偶然是distributive。这意味着它最终会分解并集,评估每个成员的类型,然后将它们并集在一起。请熟悉该文档,因为它很重要。如果您有一个类似type G<T> = T extends U ? X : Y
的类型,其中T
是一个“裸”类型参数(因此它是T extends
而不是SomethingWith<T> extends
),那么它将分布。有时这就是您想要的。现在不是。
关闭分配条件类型的最简单方法是“覆盖”裸类型参数:将T extends U ? X : Y
变成[T] extends [U] ? X : Y
。所以:
export type AreSame<T, U, R> = [T] extends [U] ? [U] extends [T] ? R : never : never;
type A = AreSame<1, 1, Object> // Object
type B = AreSame<1, 2, Object> // never
type C = AreSame<1, number, Object> // never
type D = AreSame<1, 1 | 2, Object> // never
type E = AreSame<1 | 2, 1 | 3, Object> // never
type F = AreSame<1 | 2, 1 | 2, Object> // Object
好的,希望能有所帮助;祝你好运!