为什么此CustomeXtract返回默认提取物的不同结果?
该代码解释了我的问题:
type A = {
a: number,
} | null
// Extract as defined in lib.es5.d.ts
type Extract<T, U> = T extends U ? T : never;
type CustomExtract = A extends null ? A : never;
type Result1 = Extract<A, null> // null
type Result2 = CustomExtract; // never
提取和customextract是相同的代码,其差异是提取物是一种通用类型。
另外,如相关示例,字符串| null
不扩展 null
。
那么,类型如何真正在此主题的引擎盖下工作?我可以想象,它可能会为每种类型的工会运行通用类型,然后将所有结果结合,但我想要真正的技术定义和工作。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不同之处在于
提取
是 分布式有条件类型,而您的CustomeXtract
却没有。为了使形式的条件类型
x扩展y?答:b
要分配,检查类型x
必须是“裸体类型参数”;也就是说, type参数喜欢t
in接口foo&lt; t&gt; {...}
和 naked ,因为它只是要检查的类型参数(即,t扩展...
),而不仅仅是某些表达式其中包括类型参数(例如Promise&lt; t&gt;扩展...
或[t]扩展...
)。当您推测时,分布式条件类型确实确实将其评估为检查类型
t
的每个联合元素的条件结合。因此,如果f&lt; t&gt;
是一种分配条件类型,则f&lt; a | b | C&gt;
将被评估为f&lt; a&gt; | f&lt; b&gt; | f&lt; c&gt;
。一个潜在的捕获是,无论f&lt;从不
从Never
进行评估,无论f
是什么(只要它的分配) ,因为从不
被认为是。有关更多信息,请参见我的其他答案 关于哪种分配条件类型以及它们的工作方式。
The difference is that
Extract
is a distributive conditional type, while yourCustomExtract
is not.In order for a conditional type of the form
X extends Y ? A : B
to be distributive, the checked typeX
must be a "naked type parameter"; that is, a type parameter likeT
ininterface Foo<T> {...}
, and naked in that it is just the type parameter being checked (i.e.,T extends ...
) and not just some expression that includes the type parameter (e.g.,Promise<T> extends ...
or[T] extends ...
).As you surmised, distributive conditional types do indeed evaluate as the union of the conditional for each union element of the checked type
T
. So ifF<T>
is a distributive conditional type, thenF<A | B | C>
will be evaluated asF<A> | F<B> | F<C>
. One potential catch is thatF<never>
will be evaluated asnever
no matter what the details ofF
are (as long as it's distributive), asnever
is considered to be the "empty union type".For further information, see my other answer about what distributive conditional types are and how they work.
@jcalz所说的一切都是正确的,但是我要把这个是简单的英语。
什么确实是返回 subset
t
,可分配给u
。如果t
有一些u
类型和其他类型,则我们仅获得u
类型。为什么以及如何做到这一点,尽管具有与CustomeXtract
相同的定义,那就是 @jcalz的答案。在您的情况下,
类型a
是{a:numbers}
和null
的联合。{a:numbers}
无法分配给null
,但是null
可分配给null
。因此,可分配给null
的子集为null
。type customeXtract = a扩展null?答:永远不会;
永远不会返回子集。如果满足条件,则它将返回a
的完整,如果未达到条件,则它将返回从不
。为了使
x扩展y
是正确的,x
的所有值都必须分配给y
或换句话说,x
x < /code>必须等于或狭窄,而不是
y
。a扩展null
是错误的,因为a
比null
更宽。另一方面,null扩展
是正确的。What @jcalz has said is all correct, but I'm going to try to put this is plain English.
What
Extract<T, U>
does is return the subset ofT
which is assignable toU
. IfT
has someU
types and some other types, we get just theU
types. Why and how it does this, despite having a definition that looks the same asCustomExtract
, that is @jcalz's answer.In your case,
type A
is the union of{a: number}
andnull
.{a: number}
is not assignable tonull
, butnull
is assignable tonull
. So the subset which is assignable tonull
isnull
.type CustomExtract = A extends null ? A : never;
will never return a subset. If the condition is met then it returnsA
in its entirety and if the condition is not met then it returnsnever
.In order for
X extends Y
to be true, all values ofX
must be assignable toY
or in other words,X
must be equal to or narrower thanY
.A extends null
is false becauseA
is broader thannull
. On the other hand,null extends A
is true.