Skip to content

Instantly share code, notes, and snippets.

@gearonix
Created January 26, 2024 10:13
Show Gist options
  • Save gearonix/086d31c882f2ba88684e92c86d340351 to your computer and use it in GitHub Desktop.
Save gearonix/086d31c882f2ba88684e92c86d340351 to your computer and use it in GitHub Desktop.
type UnionToIntersection<U> =
(U extends U ? (arg: U) => unknown : never) extends
((arg: infer I) => unknown) ? I : never
type LastOfUnion<U> =
UnionToIntersection<
(U extends unknown ? (arg: U) => unknown : never)
> extends (arg: infer I) => unknown ? I : never
type IsAny<T> = [T] extends [never] ?
false :
T extends (1 & T) ?
true : unknown extends T ?
true : false
type IsUnion<T, Copy = T> =
[T] extends [never] ?
false :
T extends T ?
[Copy] extends [T] ?
// using isAny here because of
// specific type-cases
IsAny<T> extends true ?
true :
false :
true :
false
type UnionToTupleImpl<U, R extends unknown[] = []> =
[U] extends [never] ?
R :
UnionToTupleImpl<Exclude<U, LastOfUnion<U>>, [...R, LastOfUnion<U>]>
type UnionToTuple<U> =
[U] extends [never] ?
never :
IsUnion<U> extends false ?
U :
UnionToTupleImpl<U>
/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'
type ExtractValuesOfTuple<T extends any[]> = T[keyof T & number]
type cases = [
Expect<Equal<UnionToTuple<'a' | 'b'>['length'], 2>>,
Expect<Equal<ExtractValuesOfTuple<UnionToTuple<'a' | 'b'>>, 'a' | 'b'>>,
// Expect<Equal<ExtractValuesOfTuple<UnionToTuple<'a'>>, 'a'>>,
Expect<Equal<ExtractValuesOfTuple<UnionToTuple<any>>, any>>,
Expect<Equal<ExtractValuesOfTuple<UnionToTuple<undefined | void | 1>>, void | 1>>,
Expect<Equal<ExtractValuesOfTuple<UnionToTuple<any | 1>>, any | 1>>,
Expect<Equal<ExtractValuesOfTuple<UnionToTuple<any | 1>>, any>>,
Expect<Equal<ExtractValuesOfTuple<UnionToTuple<'d' | 'f' | 1 | never>>, 'f' | 'd' | 1>>,
Expect<Equal<ExtractValuesOfTuple<UnionToTuple<[{ a: 1 }] | 1>>, [{ a: 1 }] | 1>>,
Expect<Equal<ExtractValuesOfTuple<UnionToTuple<never>>, never>>,
Expect<Equal<ExtractValuesOfTuple<UnionToTuple<'a' | 'b' | 'c' | 1 | 2 | 'd' | 'e' | 'f' | 'g'>>, 'f' | 'e' | 1 | 2 | 'g' | 'c' | 'd' | 'a' | 'b'>>,
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment