Created
September 6, 2023 13:44
-
-
Save cefn/d552ec3ef0b6918b5be80c9cc42cd5b9 to your computer and use it in GitHub Desktop.
Type-safe tuple composition from literal numbers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** The union of the types of members of array `Arr` */ | |
export type MemberOf<Arr extends readonly unknown[]> = Arr[number]; | |
// from https://stackoverflow.com/a/65914848/2257198 | |
type Tuple<T, N extends number, A extends unknown[] = []> = A extends { length: N } ? A : Tuple<T, N, [...A, T]>; | |
export function composeTuple<Item, Length extends number, LengthCast = [...Item[]]>(item: Item, length: Length) { | |
return Array.from({ length }).map(() => item) as LengthCast; | |
} | |
export function composeOneOrMore<Item, Length extends number>(item: Item, length: Length) { | |
if (length < 1) { | |
throw new Error(`Cannot create tuple of length ${length}`); | |
} | |
return composeTuple<Item, Length, Tuple<Item, Length, [Item]>>(item, length); | |
} | |
export function hasLength<A extends [...unknown[]], Length extends number>( | |
array: A, | |
length: Length, | |
): array is A & Tuple<MemberOf<A>, Length> { | |
return array.length === length; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment