将联合类型转换为交集类型 [英] Transform union type to intersection type

查看:27
本文介绍了将联合类型转换为交集类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法将联合类型转换为交集类型:

Is there a way to transform a union type into an intersection type :

type FunctionUnion = () => void | (p: string) => void
type FunctionIntersection = () => void & (p: string) => void

我想对 FunctionUnion 应用转换以获得 FunctionIntersection

I would like to apply a transformation to FunctionUnion to get FunctionIntersection

推荐答案

你想要并集到交集?分布式条件类型推断条件类型可以做到这一点.(不要认为有可能进行交集到联合,抱歉)这是邪恶的魔法:

You want union to intersection? Distributive conditional types and inference from conditional types can do that. (Don't think it's possible to do intersection-to-union though, sorry) Here's the evil magic:

type UnionToIntersection<U> = 
  (U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never

这会分发联合 U 并将其重新打包为一个新联合,其中所有成分都处于逆变位置.这允许将类型推断为交集 I,如手册​​中所述:

That distributes the union U and repackages it into a new union where all the consitutents are in contravariant position. That allows the type to be inferred as an intersection I, as mentioned in the handbook:

同样,逆变位置中同一类型变量的多个候选会导致推断交叉类型.

Likewise, multiple candidates for the same type variable in contra-variant positions causes an intersection type to be inferred.

<小时>

让我们看看它是否有效.


Let's see if it works.

首先让我将您的 FunctionUnionFunctionIntersection 括起来,因为 TypeScript 似乎比函数返回更紧密地绑定联合/交集:

First let me parenthesize your FunctionUnion and FunctionIntersection because TypeScript seems to bind the union/intersection more tightly than function return:

type FunctionUnion = (() => void) | ((p: string) => void);
type FunctionIntersection = (() => void) & ((p: string) => void);

测试:

type SynthesizedFunctionIntersection = UnionToIntersection<FunctionUnion>
// inspects as 
// type SynthesizedFunctionIntersection = (() => void) & ((p: string) => void)

看起来不错!

请注意,通常 UnionToIntersection<> 会暴露一些 TypeScript 认为是实际联合的细节.例如,boolean 显然在内部表示为 true |错误,所以

Be careful that in general UnionToIntersection<> exposes some details of what TypeScript thinks is an actual union. For example, boolean is apparently internally represented as true | false, so

type Weird = UnionToIntersection<string | number | boolean>

变成

type Weird = string & number & true & false

在 TS3.6+ 中被急切地减少到

which in TS3.6+ gets eagerly reduced to

type Weird = never

因为不可能有一个值是 string and number and true and false.

because it's impossible to have a value which is string and number and true and false.

希望有所帮助.祝你好运!

Hope that helps. Good luck!

这篇关于将联合类型转换为交集类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆