为什么此CustomeXtract返回默认提取物的不同结果?

发布于 2025-02-07 12:24:26 字数 493 浏览 3 评论 0 原文

该代码解释了我的问题:

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

那么,类型如何真正在此主题的引擎盖下工作?我可以想象,它可能会为每种类型的工会运行通用类型,然后将所有结果结合,但我想要真正的技术定义和工作。

The code explains my question:

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

Extract and CustomExtract are the same code, with the difference that Extract is a generic type.

Also, as related example, string | null does not extends null.

So, how types really works under the hoods at this topic? I can imagine it maybe runs the generic type for each type of the union and then unionize all the results, but I want the real technical definition and working of it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

z祗昰~ 2025-02-14 12:24:26

不同之处在于提取 分布式有条件类型,而您的 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 your CustomExtract is not.

In order for a conditional type of the form X extends Y ? A : B to be distributive, the checked type X must be a "naked type parameter"; that is, a type parameter like T in interface 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 if F<T> is a distributive conditional type, then F<A | B | C> will be evaluated as F<A> | F<B> | F<C>. One potential catch is that F<never> will be evaluated as never no matter what the details of F are (as long as it's distributive), as never 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.

薄暮涼年 2025-02-14 12:24:26

@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 of T which is assignable to U. If T has some U types and some other types, we get just the U types. Why and how it does this, despite having a definition that looks the same as CustomExtract, that is @jcalz's answer.

In your case, type A is the union of {a: number} and null. {a: number} is not assignable to null, but null is assignable to null. So the subset which is assignable to null is null.

type CustomExtract = A extends null ? A : never; will never return a subset. If the condition is met then it returns A in its entirety and if the condition is not met then it returns never.

In order for X extends Y to be true, all values of X must be assignable to Y or in other words, X must be equal to or narrower than Y.

A extends null is false because A is broader than null. On the other hand, null extends A is true.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文