Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add UnionToUnorderedTuple type #686

Closed
wants to merge 1 commit into from
Closed

Conversation

kopach
Copy link

@kopach kopach commented Sep 13, 2023

No description provided.

@sindresorhus
Copy link
Owner

Thanks for contributing.

It would be great if you could check out the previous attempt at adding this type and address the feedback given there (if relevant): #167

@kopach
Copy link
Author

kopach commented Sep 14, 2023

hi @sindresorhus , thanks for pointing this out. Yes indeed this implementation has exactly the same issues as during previous attempt. The problem is in TypeScript itself. It doesn't guarantee that tuple will always preserve order of it's elements. Closing this for now

@kopach kopach closed this Sep 14, 2023
@kopach
Copy link
Author

kopach commented Sep 14, 2023

hi @sindresorhus, just found this microsoft/TypeScript#44116 (comment)

Unions are unordered and any code that attempts to observe a union's order is asking for undefined behavior.

So, maybe we shouldn't expect tuple to be ordered in the same way as union? Personally, I would have this UnionToTuple type as it is (possibly with additional comment in docs, that order could change). I use this type in my codebase and still find it useful.

@kopach kopach reopened this Sep 14, 2023
@kopach
Copy link
Author

kopach commented Sep 14, 2023

Maybe just renaming this to UnionToUnsortedTuple to indicate this is not sorted?

@sindresorhus
Copy link
Owner

Yeah. I would go with UnionToUnorderedTuple.

@sindresorhus
Copy link
Owner

Bump :)

@mkovel
Copy link

mkovel commented Nov 14, 2023

👍

@kopach kopach changed the title Add UnionToTuple type Add UnionToUnorderedTuple type Nov 22, 2023
@kopach
Copy link
Author

kopach commented Nov 22, 2023

hi @sindresorhus, @mkovel. I started refactoring this and discovered, that there are other conceptual problems with this type. Not sure what should be the correct result in this case

type T = UnionToUnsortedTuple<boolean | 'a'>; // [false, true, 'a']

There are many more issues & attempts to solve them here: microsoft/TypeScript#13298
Not sure if we should have such a type in the library. TS should resolve this.
What do you think?

@mkovel
Copy link

mkovel commented Nov 23, 2023

@kopach Hi, honestly I didn't dive into it deeply. I just reused this code to solve the issue. Maybe it will be helpful.

export type UnionToIntersection<U> = (
  U extends never ? never : (arg: U) => never
) extends (arg: infer I) => void
  ? I
  : never;

export type UnionToTuple<T> = UnionToIntersection<
  T extends never ? never : (t: T) => T
> extends (_: never) => infer W
  ? [...UnionToTuple<Exclude<T, W>>, W]
  : [];

@jtenner
Copy link

jtenner commented Feb 21, 2024

@kopach Hi, honestly I didn't dive into it deeply. I just reused this code to solve the issue. Maybe it will be helpful.

export type UnionToIntersection<U> = (
  U extends never ? never : (arg: U) => never
) extends (arg: infer I) => void
  ? I
  : never;

export type UnionToTuple<T> = UnionToIntersection<
  T extends never ? never : (t: T) => T
> extends (_: never) => infer W
  ? [...UnionToTuple<Exclude<T, W>>, W]
  : [];

This is by far one of the most amazing types I've ever seen. It's exactly what I needed, and I don't really care much about the undefined behavior aspect. It's just for type checking and cli configuration.

Thank you so much.

@sindresorhus
Copy link
Owner

I think it's still worth adding this type, but this PR is not moving forward, so closing for now: #819

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants