Skip to content

Instantly share code, notes, and snippets.

@webstrand
Created July 15, 2025 17:34
Show Gist options
  • Save webstrand/4d8b76ef19655dc0167eeb8f8bb6e841 to your computer and use it in GitHub Desktop.
Save webstrand/4d8b76ef19655dc0167eeb8f8bb6e841 to your computer and use it in GitHub Desktop.
My favorite way of implementing Union To Tuple in TypeScript
declare const END: unique symbol;
type END = typeof END;
export type UnionToTuple<
T,
I = (() => END) &
((T extends T ? (x: () => T) => void : never) extends (x: infer U) => void
? U
: never),
Acc extends readonly unknown[] = [],
> = I extends () => infer K
? K extends END
? Acc
: UnionToTuple<T, (() => K) & I, [K, ...Acc]>
: never;
// Relies on the trick that intersecting a component of an intersection with
// the whole intersection causes the component to be reordered not duplicated.
// Relies on the fact that an intersection of function types is considered
// an overloaded function type.
// Relies on the fact that infering the type of an overloaded function returns
// inferences based on the _last_ overload which is the same as the _last_
// function type in the intersection.
// Using this technique we can rotate the intersection to visit every member
// in order until the unique symbol END is reached.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment