Slice
Challenge
Implement the JavaScript Array.slice function in the type system. Slice<Arr, Start, End> takes the three argument. The output should be a subarray of Arr from index Start to End. Indexes with negative numbers should be counted from reversely.
For example
type Arr = [1, 2, 3, 4, 5];
type Result = Slice<Arr, 2, 4>; // expected to be [3, 4]
Solution
type NormalizeIndex< T extends unknown[], I extends number, P extends unknown[] = []
=
${I}extends-${infer N}?${P['length']}extends N
? T['length']
: T extends [...infer A, infer B]
? NormalizeIndex<A, I, [...P, B]>
: T['length']
: I
type GG = NormalizeIndex<[2,3], -1>
type Slice< Arr extends number[], Start extends number = 0, End extends number = Arr[‘length’], NStart extends number = NormalizeIndex<Arr, Start>, NEnd extends number = NormalizeIndex<Arr, End>, I extends unknown[] = []
= I[‘length’] extends NEnd | Arr[‘length’] ? [] : I[‘length’] extends NStart ? […I, unknown][‘length’] extends number
? [
Arr[I['length']],
...Slice<
Arr,
Start,
End,
[...I, unknown]['length'],
NEnd,
[...I, unknown]
>
]
: never
: Slice<Arr, Start, End, NStart, NEnd, […I, unknown]>