Skip to content

Union type to "unordered" array #57321

Closed
Closed

Description

🔍 Search Terms

union type to array

✅ Viability Checklist

⭐ Suggestion

  • This feature has been rejected several times (see: Type manipulations: union to tuple #13298) due to the premise that a union type is unordered and cannot be converted into a Tuple or an Array as these have a given order.
  • While this is true the reality is that we often need to create arrays that contain all possible union type members, without caring about their positions within such arrays. Examples:
    • you want to generate all possible <option> of your <select> for all union type members, then you would most likely sort ascending anyway
    • for validation purpose with libs like zod
  • Different folks also suggested that instead of trying to get an array out of a union type, you could do the opposite: create the array of possibilities, and generate the union type out of it.
  • Unfortunately when working with schemas delivered by a backend and using tools to generate types then we gain strong guarantees but loose the ability to customize the type definition. Such type generation tools would often create union types.

Having a way to transform a union type into an "unordered" array would remove a ton of boilerplate we need to write now.

📃 Motivating Example

Allow iterating on union types, by transforming the union type into an array.

💻 Use Cases

  • The main use case is when you are not in control of type generation, e.g. a schema delivered from a backend (OpenAPI, GraphQL, etc)

Activity

  1. RyanCavanaugh commented on Feb 7, 2024

    @RyanCavanaugh
    Member

    I can't think of something you could do with this that you can't already do today.

    "Let me do the thing I'm asking for" is not a motivating example; it's begging the question. What are you trying to do?

  2. molinch commented on Feb 7, 2024

    @molinch
    Author

    Thanks Ryan for the feedback. My apologies if the intent was not clear enough.
    I will explain exactly our use case then.

    When your backend exposes a GraphQL schema, then you can generate all the types exposed by its schema. In our case we use the Relay compiler for that purpose and it generates the TypeScript types. This gives us strong guarantees.
    As such we get union types, for example we have the Language union which contains English, French, Italian or German.
    Relay compiler would create:

    type Language = "English" | "French" | "Italian" | "German"

    We then offer all these languages into a dropdown list and the user of our application can choose one language from it.

    It could be due to our lack of knowledge, I cannot be 100% sure, but right now we would create an array containing all possible languages, and we would create the dropdown entries from it. As such our code looks like:

    const languages: Language[] = ["English", "French", "Italian", "German"]
    // Then use languages to generate dropdown entries

    If we could generate such arrays from the union type members, then this step would be eliminated.
    Do you see an alternative?

  3. fatcerberus commented on Feb 7, 2024

    @fatcerberus

    If we could generate such arrays from the union type members

    So you're trying to generate a runtime-accessible array from a type definition? Yeah, that's not going to happen; it violates

    This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)

    You always have to do the reverse: write the array, then infer a type from it.

    Playground

    const languages = ["English", "French", "Italian", "German"] as const;
    type Language = typeof languages[number];
    //   ^?
  4. RyanCavanaugh commented on Feb 7, 2024

    @RyanCavanaugh
    Member

    We don't generate runtime code from type information, ever - that's a key design constraint.

    I think you'd be interested to read #53171 - this is the use case as far as I understand

  5. MichalMarsalek commented on Feb 8, 2024

    @MichalMarsalek
    Contributor

    You should instead modify the generator to generate the runtime array, that's what I do when generating typescript code from an OpenAPI schema.

  6. molinch commented on Feb 8, 2024

    @molinch
    Author

    Thanks Ryan Cavanaugh (@RyanCavanaugh) and Bruce Pascoe (@fatcerberus) you nailed it, it would be against TS goals.
    Michal Maršálek (@MichalMarsalek) that's the direction I am heading to.

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

Metadata

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