Skip to content

Instantly share code, notes, and snippets.

@AriPerkkio
Created August 13, 2024 15:17
Show Gist options
  • Save AriPerkkio/fae064b20778c6a4a54a36416a127486 to your computer and use it in GitHub Desktop.
Save AriPerkkio/fae064b20778c6a4a54a36416a127486 to your computer and use it in GitHub Desktop.
UnionToArray TS
/**
* Create an array of string literal where all types are required and allowed just once
*
* ```ts
* // Example usage: Make sure test.each() covers all cases for a string literal type
* type UserTypes = "admin" | "user" | "anonymous";
*
* test.each(["admin", "user", "anonymous"] satisfies UnionToArray<UserTypes>)
*/
type UnionToArray<
UnionType extends string,
ArrayType extends string[] = []
> = {
[StringLiteral in UnionType]: Exclude<UnionType, StringLiteral> extends never
? [...ArrayType, StringLiteral]
: UnionToArray<Exclude<UnionType, StringLiteral>, [...ArrayType, StringLiteral]>;
}[UnionType] & string[];
// Tests
type SomeType = 'ONE' | 'TWO' | 'THREE' | 'FOUR' | 'FIVE' | 'SIX' | 'SEVEN' | 'EIGHT';
const ListOfSomeTypesOrdered: UnionToArray<SomeType> = ['ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT'];
const ListOfSomeTypesUnorder: UnionToArray<SomeType> = ['ONE', 'TWO', 'FIVE', 'THREE', 'FOUR' ,'EIGHT', 'SIX', 'SEVEN'];
// @ts-expect-error
const ListOfSomeTypesMissing: UnionToArray<SomeType> = ['TWO', 'ONE', 'FIVE', 'FOUR'];
// @ts-expect-error
const ListOfSomeTypesUnknownValue: UnionToArray<SomeType> = ['ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'ELEVEN'];
// @ts-expect-error
const ListOfSomeTypesLengthNotMatching: UnionToArray<SomeType> = ['ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'EIGHT'];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment