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

730 - Union to Tuple #2161

Open
zongzi531 opened this issue Jul 9, 2021 · 2 comments
Open

730 - Union to Tuple #2161

zongzi531 opened this issue Jul 9, 2021 · 2 comments
Labels
730 answer Share answers/solutions to a question en in English

Comments

@zongzi531
Copy link
Contributor

zongzi531 commented Jul 9, 2021

// your answers
// is incorrect!
// type UnionToTuple<T> = [T] extends [never] ? never : T extends undefined ? never : [T]

/**
 * UnionToIntersection<{ foo: string } | { bar: string }> =
 *  { foo: string } & { bar: string }.
 */
type UnionToIntersection<U> = (
  U extends unknown ? (arg: U) => 0 : never
) extends (arg: infer I) => 0
  ? I
  : never;

/**
 * LastInUnion<1 | 2> = 2.
 * 
 */
type LastInUnion<U> = UnionToIntersection<
  U extends unknown ? (x: U) => 0 : never
> extends (x: infer L) => 0
  ? L
  : never;

/**
 * UnionToTuple<1 | 2> = [1, 2].
 * see https://github.com/type-challenges/type-challenges/issues/737#issuecomment-791505468
 */
type UnionToTuple<U, Last = LastInUnion<U>> = [U] extends [never]
  ? []
  : [...UnionToTuple<Exclude<U, Last>>, Last];
type h = ((x: 1) => 0) & ((x: 2) => 0) //why h not never

Function arguments are in contravariant positions, so when functions intersect, arguments do not intersect, but are united. This intersection of functions forms an overload -- a function that takes either 1 or 2 as its first argument.

type e = (((x: 1) => 0) & ((x: 2) => 0)) extends (x: infer L) => 0 ? L : never; //  why e is 2 not never or 1?

This is a feature of TS, mentioned somewhere in the documentation -- if it is necessary to output one type from overload, TS selects the last signature ((x: 2) => 0) in the overload.

@zongzi531 zongzi531 added answer Share answers/solutions to a question en in English labels Jul 9, 2021
@github-actions github-actions bot added the 730 label Jul 9, 2021
@David245M
Copy link

@zongzi531 The result type will be not a tuple of all types from union, but union of arrays with each type from union.

@zongzi531
Copy link
Contributor Author

@David245M Sorry! I found this problem just now, thanks for the reminder. I will try to challenge again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
730 answer Share answers/solutions to a question en in English
Projects
None yet
Development

No branches or pull requests

2 participants