Mag*_*nus 3 negation typescript
我想在Typescript中创建一个简单的NOT运算符,在该脚本中,您将所有原语组合到某种类型A的并集中,这些原语不是第二种类型B的并集的原语成员。这可以使用条件类型来完成。例如,如果您有以下类型:
type A = 'a' | 'b' | 'c';
type B = 'c' | 'd' | 'e';
Run Code Online (Sandbox Code Playgroud)
...那么我想将它们映射到第三个派生类型[A-B],在这种情况下,将产生:
type C = 'a' | 'b'
Run Code Online (Sandbox Code Playgroud)
使用下面所示形式的条件,这似乎是可行的。但是,我完全感到困惑,为什么下面的NOT运算符似乎给了我想要的东西,但是显式地拼写出完全相同的条件逻辑却没有:
type not_A_B_1 = A extends B ? never : A; // 'a' | 'b' | 'c'
type Not<T, U> = T extends U ? never : T;
type not_A_B_2 = Not<A, B> // 'a' | 'b'
Run Code Online (Sandbox Code Playgroud)
看这里。
有人可以告诉我我是否在这里缺少TS的细微之处,这可以解释为什么not_A_B_1并且not_A_B_2不等效吗?谢谢。
您遇到了分布式条件类型:
其中选中的类型为裸类型参数的条件类型称为分布式条件类型。实例化期间,分布条件类型自动在联合类型上分布。例如,
T extends U ? X : Y使用类型参数A | B | Cfor 的实例化T被解析为(A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y)
因此在此:
type not_A_B_1 = A extends B ? never : A; // 'a' | 'b' | 'c'
Run Code Online (Sandbox Code Playgroud)
的A是一个具体的类型,而不是一个类型参数,所以有条件的类型不得到分布在它的成分。
但在
type Not<T, U> = T extends U ? never : T;
Run Code Online (Sandbox Code Playgroud)
的T是一个赤裸裸的类型参数,所以有条件的类型没有得到分配。“裸”是什么意思?这意味着T相对于某些类型的功能T。因此,在中{foo: T} extends W ? X : Y,类型参数T为“ clothed”,因此不会分布。
这导致一种不需要时可以关闭分布式条件类型的方法:给type参数穿上衣服。执行此操作的最简单且最不冗长的方法是使用一个元素的元组:
T extends U ? V : W // naked T
[T] extends [U] ? V : W // clothed T
Run Code Online (Sandbox Code Playgroud)
由于[T] extends [U]确切的时间应为true T extends U,所以除了分布性外,它们是等效的。因此,让我们更改Not<>为非分布式:
type NotNoDistribute<T, U> = [T] extends [U] ? never : T;
type not_A_B_2 = NotNoDistribute<A, B> // 'a' | 'b' | 'c'
Run Code Online (Sandbox Code Playgroud)
现在not_A_B_2与相同not_A_B_1。如果您喜欢原始not_A_B_2行为,请使用分布式条件类型,例如Not<>。如果您喜欢非分配行为,请使用具体类型或衣服类型参数。那有意义吗?
顺便说一句,您的Not<T,U>类型已经作为标准库中的预定义类型存在Exclude<T,U>,表示“是从T可分配给这些类型的类型中排除U”。
希望能有所帮助。祝好运!
| 归档时间: |
|
| 查看次数: |
307 次 |
| 最近记录: |