泛型声明中的差异

时间:2019-06-22 15:11:08

标签: typescript

在打字稿中,两者之间有区别

a : T<x> | T<y> 

a : T<x | y>

2 个答案:

答案 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,反之亦然。如果VT<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} },这只是证据,对于一般XY是正确的,而不是证明。显然,如果我选择T<X | Y>T<X> | T<Y>为同一类型,那么X将始终等于Y。因此,我刚刚选择了一个足够不同的XY进行说明。

好的,让我们开始吧:


以下是一些通用类型,它们在类型参数中的联合上分布 ,其中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的某些特定情况下,已知可以通过工会进行分配,在这些情况下没有区别。通常,尽管有所不同。

好的,希望能有所帮助。祝你好运!

Link to code

答案 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的展示。