Skip to content

Instantly share code, notes, and snippets.

@ryangoree
Last active January 24, 2025 21:01
Show Gist options
  • Save ryangoree/c5b4b4be3d169ef128bbf338ecc528cf to your computer and use it in GitHub Desktop.
Save ryangoree/c5b4b4be3d169ef128bbf338ecc528cf to your computer and use it in GitHub Desktop.
Get a sliced subset of a tuple type.
type BuildTuple<
L extends number,
T extends any[] = [],
F = unknown,
> = `${L}` extends `-${number}`
? never
: T["length"] extends L
? T
: BuildTuple<L, [...T, F], F>;
type Abs<T extends number> = `${T}` extends `-${infer N extends number}`
? N
: T;
type IsNegative<T extends number> = `${T}` extends `-${number}` ? true : false;
type CutStarting<T extends any[], N extends number> = T extends [
...BuildTuple<N>,
...infer Rest,
]
? Rest
: [];
type CutEnding<T extends any[], N extends number> = T extends [
...infer Rest,
...BuildTuple<N>,
]
? Rest
: [];
type GetEnding<T extends any[], N extends number> = T extends [
...CutEnding<T, N>,
...infer Rest,
]
? Rest
: [];
type GetStarting<T extends any[], N extends number> = T extends [
...infer Rest,
...CutStarting<T, N>,
]
? Rest
: [];
type SliceStart<
Tuple extends any[],
StartIndex extends number,
> = IsNegative<StartIndex> extends true
? GetEnding<Tuple, Abs<StartIndex>>
: CutStarting<Tuple, StartIndex>;
type SliceEnd<
Tuple extends any[],
EndIndex extends number,
> = IsNegative<EndIndex> extends true
? CutEnding<Tuple, Abs<EndIndex>>
: GetStarting<Tuple, EndIndex>;
type OverLap<T extends any[], U extends any[]> = T extends U
? T
: T extends [...infer O, infer Last]
? U extends [...any[], infer End]
? Last extends End
? T
: OverLap<O, U>
: []
: [];
type Slice<
Tuple extends any[],
StartIndex extends number,
EndIndex extends number = Tuple["length"],
> = OverLap<SliceStart<Tuple, StartIndex>, SliceEnd<Tuple, EndIndex>>;
type Nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// [].slice(4, 7)
type Sliced = Slice<Nums, 4, 7>; // => [4, 5, 6]
// [].slice(-2)
type Sliced2 = Slice<Nums, -2>; // => [9, 10]
// [].slice(-2, -1)
type Sliced3 = Slice<Nums, -2, -1>; // => [9]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment