在打字稿中,两者之间有区别
a : T<x> | T<y>
和
a : T<x | y>
答案 0 :(得分:4)
这完全取决于T
的定义,此处不包括。由于代码似乎不是minimum reproducible example,因此我们只能笼统地说。
当您说T<X | Y>
等同于所有T<X> | T<Y>
和X
的{{1}}时,您是说Y
distributes超过了联合在其类型参数中。通常,T<X>
不会不分布在其类型参数上。 可以发生,但通常不会发生。
为了探讨一些案例,让我们介绍一些测试设备:
T<X>
type Compare<U, V> = [U] extends [V]
? ([V] extends [U] ? "mutually assignable" : "subtype")
: [V] extends [U] ? "supertype" : "unrelated";
类型将比较类型Compare<U, V>
和U
,以查看V
是否可分配给U
,反之亦然。如果V
与T<X | Y>
相同,则T<X> | T<Y>
应该返回Compare<T<X | Y>, T<X> | T<Y>>
。如果不是,那么您将获得其他三种可能性之一:"mutually assignable"
是T<X | Y>
的超类型(即T<X> | T<Y>
可分配给{{ 1}})或T<X> | T<Y>
是T<X | Y>
的子类型(即T<X | Y>
可分配给T<X> | T<Y>
)或{{1 }}与T<X | Y>
无关(也就是说,两种类型都不能分配给另一种)。
T<X> | T<Y>
我在这里为T<X | Y>
和T<X> | T<Y>
提供了一些 specific 示例,因此在以下测试中,如果type X = { a: string; b: number } | number;
type Y = { c: boolean; d: any[] } | string;
被声明为等同于{{1} },这只是证据,对于一般X
和Y
是正确的,而不是证明。显然,如果我选择T<X | Y>
和T<X> | T<Y>
为同一类型,那么X
将始终等于Y
。因此,我刚刚选择了一个足够不同的X
和Y
进行说明。
好的,让我们开始吧:
以下是一些通用类型,它们在类型参数中的联合上分布 ,其中T<X | Y>
等效于T<X> | T<Y>
:
•不引用其type参数的常量类型函数是分布式的:
X
•身份类型功能是分布式的:
Y
•类型参数与某些内容的并集是分布式的:
T<X> | T<Y>
•type参数与某些东西的交集是分布式的:
T<X | Y>
•一个conditional type in which the checked type is the "naked" type parameter(所以只有type Constant<T> = string;
type ConstantDistributes = Compare<Constant<X | Y>, Constant<X> | Constant<Y>>;
// mutually assignable
而不是type Identity<T> = T;
type IdentityDistributes = Compare<Identity<X | Y>, Identity<X> | Identity<Y>>;
// mutually assignable
)是分布式的:
type OrSomething<T> = T | { z: string };
type OrSomethingDistributes = Compare<
OrSomething<X | Y>,
OrSomething<X> | OrSomething<Y>
>; // mutually assignable
•在其type参数中为bivariant的泛型类型是分布式的。这是非常罕见的,因为双变量类型通常是不正确的。 TypeScript中的方法参数为treated as bivariant。如果关闭--strictFunctionTypes
...,通常将函数参数视为双变量,但不应将其关闭。
type AndSomething<T> = T & { z: string };
type AndSomethingDistributes = Compare<
AndSomething<X | Y>,
AndSomething<X> | AndSomething<Y>
>; // mutually assignable
专门选择这些案例以使等价成立。现在,对于更常见的情况,它们不等效:
•在其type参数中为covariant的通用类型将不分发。在此类类型中,T extends ...
将是SomeFunctionOf<T> extends ...
的超类型:
type NakedConditional<T> = T extends object ? { x: T } : { y: T };
type NakedConditionalDistributes = Compare<
NakedConditional<X | Y>,
NakedConditional<X> | NakedConditional<Y>
>; // mutually assignable
•在其type参数中为contravariant的通用类型将不分发。在此类类型中,interface Bivariant<T> {
method(x: T): void;
}
type BivariantDistributes = Compare<
Bivariant<X | Y>,
Bivariant<X> | Bivariant<Y>
>;
// mutually assignable
将是T<X | Y>
的子类型:
T<X> | T<Y>
•在其type参数中为invariant的通用类型将不分发。在此类类型中,interface Covariant<T> {
prop: T;
}
type CovariantIsASupertype = Compare<
Covariant<X | Y>,
Covariant<X> | Covariant<Y>
>;
// supertype
与T<X | Y>
中的 不相关:
T<X> | T<Y>
回顾一下。在不了解interface Contravariant<T> {
(arg: T): void;
}
type ContravariantIsASubtype = Compare<
Contravariant<X | Y>,
Contravariant<X> | Contravariant<Y>
>;
// subtype
的情况下,您不能指望T<X | Y>
和T<X> | T<Y>
的{{1}}都等同于interface Invariant<T> {
(arg: T): T;
}
type InvariantIsUnrelated = Compare<
Invariant<X | Y>,
Invariant<X> | Invariant<Y>
>;
// unrelated
。在T
的某些特定情况下,已知可以通过工会进行分配,在这些情况下没有区别。通常,尽管有所不同。
好的,希望能有所帮助。祝你好运!
答案 1 :(得分:0)
不相同。
a: T<x> | T<y>
表示a
的类型是T<x>
或类型为T<y>
的。
a: T<x | y>
表示a
的类型为T
,其中T
的类型为x | y
。
任何类型T<x> | T<y>
的值都可以分配给任何类型T<x | y>
的变量,但不能相反。
我做了quick demonstration的展示。