Last active
January 24, 2025 21:01
-
-
Save ryangoree/c5b4b4be3d169ef128bbf338ecc528cf to your computer and use it in GitHub Desktop.
Get a sliced subset of a tuple type.
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
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