typescript 文字联合

标签 typescript

我有两个文字类型,我想从联合 A 中排除 B。

type A = 'a' | 'b'
type B = 'a'

当我这样做时:

type MyExclude<A2, B2> = A2 extends B2 ? never : A2
type C2 = MyExclude<A, B>
// C2 = 'b'

它工作正常,即我得到“b”。

但是当我这样直接做的时候:

type C = A extends B ? never : A
// C = 'a' | 'b'

事实并非如此。为什么我是通过中间泛型类型还是直接这样做很重要?

谢谢。

最佳答案

当您将其作为泛型执行时,Typescript 会将检查分布地应用于联合体的每个成员。所以type C2 = MyExclude<A, B>将不会被评估为 'a | b' extends 'a' ? never : 'a | 'b' ,而是 ('a' extends 'a' ? never : 'a') | ('b' extends 'a' ? never : 'b') . 'a' 确实扩展了 B,因此结果为 never . 'b' 不扩展 B,因此结果为 'b'。最后的结果是never | 'b' , 这就是 'b' .

如果不是泛型,则分配部分不会发生。 type C = A extends B ? never : A将被评估一次,如'a | b' extends 'a' ? never : 'a | 'b' . 'a' | 'b'不扩展 'a' ,所以结果是整个类型,'a' | 'b'

参见 distributive conditional types

Distributive conditional types

Conditional types in which the checked type is a naked type parameter are called distributive conditional types. Distributive conditional types are automatically distributed over union types during instantiation. For example, an instantiation of T extends U ? X : Y with the type argument A | B | C for T is resolved as (A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y).

关于 typescript 文字联合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73744524/

相关文章:

typescript - 如何在没有Webpack的 typescript 节点项目中使用.graphql

typescript - 如何强制对象将所有枚举值包含为属性键?

javascript - 使用 typescript 枚举并对期望字符串 Prop 使用react

javascript - 以 Angular 4 在路由器导出外加载页面

typescript - 如何合并命名空间在 TypeScript 中没有导出接口(interface)

javascript - 从主页导航时导航到页面并突出显示菜单项

arrays - TypeScript:reduce 函数 - 没有重载匹配这个调用

angular - 动态更改 angular2-query-builder 中的配置

json - 不能在 *ngFor : angular2 中使用 *ngIF

angular - 如何在嵌套的 Json 对象中获取循环