How to transform union type to tuple type

后端 未结 2 1801
半阙折子戏
半阙折子戏 2020-11-27 08:42

For example i have type

type abc = \'a\' | \'b\' | \'c\';

How to make tuple type that contains all elements of the union in compile time?

2条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-11-27 09:12

    It's easy to convert from a tuple type to a union type; for example, see this question. But the opposite, converting from a union to a tuple is one of those Truly Bad Ideas that you shouldn't try to do. Let's do it first and scold ourselves later:

    // oh boy don't do this
    type UnionToIntersection =
      (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never
    type LastOf =
      UnionToIntersection T : never> extends () => (infer R) ? R : never
    
    // TS4.0+
    type Push = [...T, V];
    
    // TS4.1+
    type TuplifyUnion, N = [T] extends [never] ? true : false> =
      true extends N ? [] : Push>, L>
    
    type abc = 'a' | 'b' | 'c';
    type t = TuplifyUnion; // ["a", "b", "c"] 
    

    Playground link

    That kind of works, but I really really REALLY recommend not using it for any official purpose or in any production code. Here's why:

    • You can't rely on the ordering of a union type. It's an implementation detail of the compiler; since X | Y is equivalent to Y | X, the compiler feels free to change one to the other. And sometimes it does:

        type TypeTrue1A = TuplifyUnion; // [true, 1, "a"] 

提交回复
热议问题