import type {Sum} from './sum'; import type {LessThan} from './less-than'; import type {LessThanOrEqual} from './less-than-or-equal'; import type {IsNegative} from './numeric'; import type {And} from './internal'; import type {IsEqual} from './is-equal'; /** Returns an array slice of a given range, just like `Array#slice()`. @example ``` import type {ArraySlice} from 'type-fest'; type T0 = ArraySlice<[0, 1, 2, 3, 4]>; //=> [0, 1, 2, 3, 4] type T1 = ArraySlice<[0, 1, 2, 3, 4], 0, -1>; //=> [0, 1, 2, 3] type T2 = ArraySlice<[0, 1, 2, 3, 4], 1, -2>; //=> [1, 2] type T3 = ArraySlice<[0, 1, 2, 3, 4], -2, 4>; //=> [3] type T4 = ArraySlice<[0, 1, 2, 3, 4], -2, -1>; //=> [3] type T5 = ArraySlice<[0, 1, 2, 3, 4], 0, -999>; //=> [] function arraySlice< const Array_ extends readonly unknown[], Start extends number = 0, End extends number = Array_['length'], >(array: Array_, start?: Start, end?: End) { return array.slice(start, end) as ArraySlice; } const slice = arraySlice([1, '2', {a: 3}, [4, 5]], 0, -1); typeof slice; //=> [1, '2', { readonly a: 3; }] slice[2].a; //=> 3 // @ts-expect-error -- TS2493: Tuple type '[1, "2", {readonly a: 3}]' of length '3' has no element at index '3'. slice[3]; ``` @category Array */ export type ArraySlice< Array_ extends readonly unknown[], Start extends number = 0, End extends number = Array_['length'], > = ArraySliceHelper; type ArraySliceHelper< Array_ extends readonly unknown[], Start extends number = 0, End extends number = Array_['length'], TraversedElement extends Array = [], Result extends Array = [], ArrayLength extends number = Array_['length'], PositiveS extends number = IsNegative extends true ? Sum extends infer AddResult extends number ? number extends AddResult // (ArrayLength + Start) < 0 ? 0 : AddResult : never : Start, PositiveE extends number = IsNegative extends true ? Sum : End, > = true extends [IsNegative, LessThanOrEqual][number] ? [] : ArraySliceByPositiveIndex; type ArraySliceByPositiveIndex< Array_ extends readonly unknown[], Start extends number, End extends number, TraversedElement extends Array = [], Result extends Array = [], > = Array_ extends readonly [infer H, ...infer Rest] ? And< IsEqual, true>, IsEqual, true> > extends true ? ArraySliceByPositiveIndex : ArraySliceByPositiveIndex : Result;