Typescript分发条件类型

gev0vcfq  于 2022-12-01  发布在  TypeScript
关注(0)|答案(2)|浏览(199)

所以我正在浏览关于 typescript 的文档,我不能理解这个概念。
所以文件上说:
在分配条件类型T extends U ? X : Y的示例化中,条件类型内对T的引用被解析为联合类型的各个组成部分(即T指的是在条件类型分布在并集类型上之后的各个成分)。此外,对x1M4N1x内的x1M3N1x的引用具有附加类型参数约束x1M5N1x(即,x1M6N1x被认为可分配给x1M8N1x内的x1M7N1x)。
我看不懂T refers to the individual constituents after the conditional type is distributed over the union type部分。
任何人都可以请解释这一点给我。一个相同的例子将是高度赞赏,在文件中的一个不是很清楚,我。

dvtswwa3

dvtswwa31#

嗯,我刚刚通读了文档,它对我来说是有意义的...我不知道我是否能解释得更好,但是让我们来看看它。在下面的内容中,...x...意味着“x可能出现的一些表达式”。
检查类型为裸类型参数的条件类型称为 * 分配条件类型 *。
在这种情况下,type parameter 表示generic type parameter,而 naked type parameter是一个类型表达式,其中type参数单独出现,而不是某个更复杂的类型表达式的一部分。checked type 是出现在extends之前的类型。让我们看一些示例:

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

散发条件型别会在执行严修化期间自动散发至等位型别。例如,T extends U ? X : Y的执行严修化(其型别参数A | B | CT)会解析为(A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y)
这是distributive属性的本质。如果您将类型别名F<T>定义为分配条件类型,如下所示:

type F<T> = T extends ...T... ? ...T... : ...T...

然后F<T>将分布在联合上,这意味着对于 * 任何 * 类型AB,类型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...,并插入A,得到T(以得到A extends ...A... ? ...A... : ...A...),然后为T插入B(以得到B extends ...B... ? ...B... : ...B...),然后合并它们。
让我们看一个具体的例子:

type D<T> = T extends string ? T : "nope"

这是什么:

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

好吧,下面是如何 * 不 * 这样做:

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

type E = "nope" //👎

我只是将"a" | "b" | 0 | true插入T而没有分发,这是错误的。下面是正确的操作方法:

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" //👍

看,我们取了“联盟的个体成分”,并依次用它们中的每一个替换T
好吧,我希望现在说得更有意义了,祝你好运!

vhmi4jdf

vhmi4jdf2#

在分配条件类型中(比如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 },而是依次引用它的每个组成部分。

相关问题