Skip to content

Type manipulations: union to tuple #13298

Closed

Description

A suggestion to create a runtime array of union members was deemed out of scope because it would not leave the type system fully erasable (and because it wouldn't be runtime complete, though that wasn't desired). This suggestion is basically a variant of that one that stays entirely within the type domain, and thus stays erasable.

The suggestion is for a keyword similar to keyof that, when given a union type, would result in a tuple type that includes each possibility in the union.

Combined with the suggestion in this comment to instead implement a codefix to create the array literal, this could be used to ensure that 1. the array was created correctly to begin with, and 2. that any changes to the union cause an error requiring the literal array to be updated. This allows creating test cases that cover every possibility for a union.

Syntax might be like this:

type SomeUnion = Foo | Bar;

type TupleOfSomeUnion = tupleof SomeUnion; // has type [Foo, Bar]

type NestedUnion = SomeUnion | string;

type TupleOfNestedUnion = tupleof NestedUnion; // has type [Foo, Bar, string]

Some issues I foresee:

  1. I don't know what ordering is best (or even feasible), but it would have to be nailed down in some predictable form.

  2. Nesting is complicated.

  3. I expect generics would be difficult to support?

  4. Inner unions would have to be left alone, which is somewhat awkward. That is, it would not be reasonable to turn Wrapper<Foo|Bar> into [Wrapper<Foo>, Wrapper<Bar>] even though that might (sometimes?) be desirable. In some cases, it’s possible to use conditional types to produce that distribution, though it has to be tailored to the particular Wrapper. Some way of converting back and forth between Wrapper<Foo|Bar> and Wrapper<Foo>|Wrapper<Bar> would be nice but beyond the scope of this suggestion (and would probably require higher-order types to be a thing).

  5. My naming suggestions are weak, particularly tupleof.

NOTE: This suggestion originally also included having a way of converting a tuple to a union. That suggestion has been removed since there are now ample ways to accomplish that. My preference is with conditional types and infer, e.g. ElementOf<A extends unknown[]> = A extends (infer T)[] ? T : never;.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    DeclinedThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions