将TypeScript联合类型分解为特定类型 [英] Decompose a TypeScript union type into specific types

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

问题描述

我想知道是否可以将联合类型拆分"为TypeScript中的特定子类型.这是我尝试使用的代码,很明显,我正在尝试从代码片段中实现以下目标:

I wonder whether it's possible to "split" union types into the specific subtypes in TypeScript. This is the code I tried to use, it should be obvious what I'm trying to achieve from the snippet:

type SplitType<T> =
T extends (infer A)|(infer B)
? Something<A, B>
: T;

在此示例中,Something<A, B>可以是[A, B],或者是完全不同的类型.这意味着SplitType<string>只会输出string,但是SplitType<number|string>表示[number, string].

In this example Something<A, B> could be [A, B], or a completely different type. This would mean that SplitType<string> would just output a string, but SplitType<number|string> would mean [number, string].

在TypeScript中是否有可能做到这一点?如果没有的话,将来是否有一项功能可以允许这样做(例如杂色类型)?

Is something like that possible in TypeScript? And if not, is there a feature that will allow this in the future (eg. variadic types)?

推荐答案

对于固定数量的工会成员,我们可以通过生成调用签名的交集然后对其进行匹配,以单个实现定义的顺序提取工会成员.针对具有多个呼叫签名的类型.此版本仅在启用strictFunctionTypes的情况下起作用.

For a fixed maximum number of union members, we can extract the union members in a single implementation-defined order by generating an intersection of call signatures and then matching it against a type with multiple call signatures. This version only works with strictFunctionTypes enabled.

// https://stackoverflow.com/a/50375286
type UnionToIntersection<U> = 
  (U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never

type UnionToFunctions<U> =
    U extends unknown ? (k: U) => void : never;

type IntersectionOfFunctionsToType<F> =
    F extends { (a: infer A): void; (b: infer B): void; (c: infer C): void; } ? [A, B, C] :
    F extends { (a: infer A): void; (b: infer B): void; } ? [A, B] :
    F extends { (a: infer A): void } ? [A] :
    never;

type SplitType<T> =
    IntersectionOfFunctionsToType<UnionToIntersection<UnionToFunctions<T>>>;

type Test1 = SplitType<number>;                    // [number]
type Test2 = SplitType<number | string>;           // [string, number]
type Test3 = SplitType<number | string | symbol>;  // [string, number, symbol]

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

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