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.

Revisions

  1. sno2 revised this gist Mar 18, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion locked-array-type.ts
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,7 @@ 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!
    type Foo3 = Locked<45, false | string>; // (false | string)[] & { 0: false | string; length: 45; } <- no overflow!

    const foo1: Foo1 = [true, true];

  2. sno2 created this gist Mar 18, 2021.
    24 changes: 24 additions & 0 deletions locked-array-type.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    /** 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