打字稿分配条件类型

Amo*_*pta 13 typescript

所以我正在阅读有关打字稿的文档,但无法理解这个概念。

所以文档说明:-

在分配条件类型的实例中,T 扩展了 U ? X : Y,在条件类型中对 T 的引用被解析为联合类型的单个成分(即 T 指的是在条件类型分布在联合类型上之后的单个成分)。此外,在 X 中对 T 的引用有一个额外的类型参数约束 U(即 T 被认为可分配给 X 中的 U)。

我无法理解这部分T refers to the individual constituents after the conditional type is distributed over the union type

任何人都可以向我解释这一点。一个相同的例子将受到高度赞赏,文档中的那个对我来说不是很清楚。

jca*_*alz 26

嗯,我只是通读了文档,这对我来说很有意义......我不知道我是否能更好地解释它,但让我们通过它。在下文中, 和...x...表示“x可能出现的某种表达方式”。

被检查类型是裸类型参数的条件类型称为分布条件类型

在这种情况下,类型参数意味着泛型类型参数类型参数是一个类型表达式,其中类型参数单独出现,而不是一些更复杂的类型表达式的一部分。并且选中的类型是之前出现的类型extends。让我们看一些例子:

  • type A<T> = string extends T ? "yes" : "no" 这不是分配条件类型。检查的类型是string,它不是泛型类型参数。
  • type B<T> = {x: T} extends {x: number} ? "yes" : "no" 这不是分配条件类型。检查的类型是{x: T},其中包含类型参数T,但不是类型参数。
  • type C<T> = T extends string ? "yes" : "no"这是一个分配条件类型;检查的类型是T,它是一个裸泛型类型参数。

在实例化期间,分布条件类型会自动分布在联合类型上。例如,具有T extends U ? X : Y类型参数A | B | Cfor的实例化T被解析为(A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y)

这就是分配属性的本质。如果您将类型别名F<T>定义为分布式条件类型,如:

type F<T> = T extends ...T... ? ...T... : ...T...
Run Code Online (Sandbox Code Playgroud)

然后F<T>将分布在联合上,这意味着对于任何类型Aand B,类型F<A | B>将等价于类型F<A> | F<B>

在分配条件类型的实例化中,对条件类型内的T extends U ? X : Y引用T被解析为联合类型的各个组成部分(即T,在条件类型分布在联合类型上之后指代各个组成部分)。

这是让您感到困惑的部分,但它只是解释了发行版的工作原理。这是说要评估F<A | B>,你应该评估F<A> | F<B>。因此,对F<A>,你拿F<T> = T extends ...T... ? ...T... : ...T...在插头AT(获得A extends ...A... ? ...A... : ...A...),然后将其插入BT(得到B extends ...B... ? ...B... : ...B...),然后他们团结起来。

我们来看一个具体的例子:

type D<T> = T extends string ? T : "nope"
Run Code Online (Sandbox Code Playgroud)

这是什么:

type E = D<"a" | "b" | 0 | true> 
Run Code Online (Sandbox Code Playgroud)

好吧,这是这样做的方法:

type E = ("a" | "b" | 0 | true) extends string ? ("a" | "b" | 0 | true) : "nope" //

type E = "nope" //
Run Code Online (Sandbox Code Playgroud)

我刚刚插入"a" | "b" | 0 | trueT不分配,这是错误的。以下是如何正确执行此操作:

type E = D<"a"> | D<"b"> | D<0> | D<true> //

type E = ("a" extends string ? "a" : "nope") |
         ("b" extends string ? "b" : "nope") |
         (0 extends string ? 0 : "nope") |
         (true extends string ? true : "nope") //

type E = ("a") | ("b") | ("nope") | ("nope") //

type E = "a" | "b" | "nope" //
Run Code Online (Sandbox Code Playgroud)

看,我们把“工会的个人组成部分”T依次替换为他们中的每一个。

好的,我希望现在更有意义。祝你好运!

  • 我认为 jcalz 必须用他自己的 Stackoverflow 答案重写整个 Typescript 文档,最终会更容易理解:) (3认同)
  • 一个非常透彻的解释,总是很高兴阅读你的东西:) (2认同)
  • 但为什么条件语句是分布式的呢?这是结果还是设计?是_“裸露”_或更具体地说是缺乏明确的实现选择,还是类型的盒装版本,例如“[T]扩展任何”在计算上如此不同,以至于它们“破坏”了分布?分别解决每个联合成员是否比尝试进入条件分支更容易? (2认同)

Tit*_*mir 5

在分布式条件类型(假设type BoxIfObject<T> = T extends object ? Array<T> : T;)中,当类型应用于联合(假设number | { a : string })时,就好像条件类型应用于联合的每个组成部分,因此在条件类型T中将依次引用联合的每个组成部分工会(T首先是number,然后T{ a : string }

所以当我们申请时BoxIfObject<number | { a : string }>T永远不会引用整个联合,number | { a : string }而是依次引用它的每个组成部分。基本上BoxIfObject<number | { a : string }> = BoxIfObject<number> | BoxIfObject<{ a : string }> = number | Array<{ a : string }

  • @AmolGupta 我不能谈论斜体的选择......但它似乎与我写的一致,当(即之后)实例化发生时,`T` 将依次成为联合的每个组成部分。 (3认同)