【问题标题】:Exclude definition conflicts Typescript排除定义冲突打字稿
【发布时间】:2020-06-08 22:35:23
【问题描述】:

下面是Exclude在各种博客上浮动的实现(一个Reference

type Exclude<T, U> = T extends U ? never : T; 根据 Typescript 博客,它通过从联合类型中排除一些属性来构造一个新类型。完美,我明白了。

让我们详细说明一下。

如果 T 扩展 U 它永远不会返回。很公平。扩展意味着我们正在继承所有属性。 (Reference - https://stackoverflow.com/a/38834997/1096194)

令人困惑的是,如果三元条件返回 false,它不应该返回 T - U 而不是 T,因为我们可能只想返回 T - U 属性,以防 T 不是 U 的扩展。

举个例子#1

U = "name", T = "id" | "name";

如果我理解正确,T extends U 在这种情况下是错误的,因为T 没有从U 继承所有属性。所以,我们应该返回T-U,即“id”,它是排除运算符的期望输出。

让我们再举一个例子#2

U = "name", T = "id" | "email"

在这种情况下,三元也失败了,因为T 没有从U 扩展或继承任何东西。所以它应该返回T - U,即id | email在这种情况下恰好等于T

那么,究竟什么是正确的定义,即T extends U? never: TT extends U? never: T - U

【问题讨论】:

  • 我不确定你的问题是否清楚。你问的是distributivity of conditionals over unions吗?文档的第一段应该解释为什么原来的定义有效。
  • 这回答了我的问题。不知道“条件对联合的分配”?

标签: typescript


【解决方案1】:

正如@artcorpse 在 cmets 中所说,条件类型是这样解析的:

with T = A | B | C;

T extends U ? X : Y

意思

(A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y)

所以在你的例子中:

U = "name";
T = "id" | "name";

T extends U ? X : Y
=>
("id" extends "name" ? never | "id") | ("name" extends "name" ? never | "id")
=>
"id" | never
=>
"id"

https://www.typescriptlang.org/docs/handbook/advanced-types.html#distributive-conditional-types

“在分布式条件类型 T 扩展 U ? X : Y 的实例中,条件类型中对 T 的引用被解析为联合类型的各个组成部分(即 T 指的是条件类型分布后的各个组成部分联合类型)。”

【讨论】:

    猜你喜欢
    • 2016-11-21
    • 2013-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多