Skip to content

Instantly share code, notes, and snippets.

@sno2
Last active March 18, 2021 22:29
Show Gist options
  • Save sno2/c64dcb2eb8d65f39763e9cb588a39e7b to your computer and use it in GitHub Desktop.
Save sno2/c64dcb2eb8d65f39763e9cb588a39e7b to your computer and use it in GitHub Desktop.
/** Makes a tuple of length `L` with each of the elements of type `T`. */
export type Locked<
L extends number,
T,
$Draft extends unknown[] | readonly unknown[] = []
> =
// jus making my ternaries look nicer in prettier
$Draft["length"] extends L
? $Draft // ship it
: $Draft["length"] extends 44 // it will overflow if it's larger than 44 so we need to do the hacky way
? T[] & { 0: T; length: L }
: Locked<L, T, [...$Draft, T]>;
type Foo1 = Locked<2, true>; // [true, true]
type Foo2 = Locked<44, string>; // [string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, ... 22 more ..., string]
type Foo3 = Locked<45, false | string>; // (false | string)[] & { 0: false | string; length: 45; } <- no overflow!
const foo1: Foo1 = [true, true];
const foo2: Foo2 = ["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""];
const foo3: Foo3 = [...foo2, false]; // `foo2`'s type is explicitly declared so it can compute the expression's type
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment