排除定义冲突打字稿

时间:2020-02-25 08:36:08

标签: typescript

以下是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

让我们举一个例子

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

如果我正确理解,T扩展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

1 个答案:

答案 0 :(得分:1)

正如@artcorpse在评论中所说,条件类型的解析如下:

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指的是条件类型分布在联合类型)。”