Bir*_*sky 7 functional-programming typescript
我是条件类型的新手,所以我尝试了最明显的静态方法,没有成功:
type NoUnion<Key> =
Key extends 'a' ? 'a' :
Key extends 'b' ? 'b' :
never;
type B = NoUnion<'a'|'b'>;
Run Code Online (Sandbox Code Playgroud)
B型仍然是一个联盟.有人请你上学吗?
这是一个游乐场.
Tit*_*mir 10
我不能确定这种情况的用例是什么,但我们可以强制NoUnion到never如果传递的类型是union类型.
正如其他提到的条件类型在联合上分布一样,这称为分布式条件类型
检查类型是裸类型参数的条件类型称为分布式条件类型.分布式条件类型在实例化期间自动分布在联合类型上.例如,T的实例化扩展了U?X:Y,类型参数为A | B | T的C被解析为(A扩展U?X:Y)| (B扩展U?X:Y)| (C扩展U?X:Y).
键是'裸类型',如果我们将类型包装在元组类型中,例如条件类型将不再是分布式的.
type UnionToIntersection<U> =
(U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never
type NoUnion<Key> =
// If this is a simple type UnionToIntersection<Key> will be the same type, otherwise it will an intersection of all types in the union and probably will not extend `Key`
[Key] extends [UnionToIntersection<Key>] ? Key : never;
type A = NoUnion<'a'|'b'>; // never
type B = NoUnion<'a'>; // a
type OtherUnion = NoUnion<string | number>; // never
type OtherType = NoUnion<number>; // number
type OtherBoolean = NoUnion<boolean>; // never since boolean is just true|false
Run Code Online (Sandbox Code Playgroud)
最后一个例子是一个问题,因为boolean是由编译器所看到true|false,NoUnion<boolean>实际上会never.如果没有更多关于你究竟想要实现的细节,很难知道这是否是一个交易破坏者,但它可以通过boolean作为一个特例来解决:
type NoUnion<Key> =
[Key] extends [boolean] ? boolean :
[Key] extends [UnionToIntersection<Key>] ? Key : never;
Run Code Online (Sandbox Code Playgroud)
注意:UnionToIntersection取自这里
顺便说一句,我试图提出的“更简单”的代码是这样的:
type NotAUnion<T> = [T] extends [infer U] ?
U extends any ? [T] extends [U] ? T : never : never : never;
Run Code Online (Sandbox Code Playgroud)
这应该可以工作(请进行测试;不知道为什么我对另一个问题的回答是错误的,但是现在已经修复了)。这与的想法类似UnionToIntersection:如果您要T分配类型,则要确保将其分配给每个部分T。通常,只有T具有一个组成部分的联合(也称为“非联合”)才是正确的。
无论如何,@ TitianCernicovaDragomir的答案也很好。只是想在那里获得该版本。干杯。