import type {BuildTuple, StaticPartOfArray, VariablePartOfArray} from './internal'; import type {GreaterThanOrEqual} from './greater-than-or-equal'; import type {Subtract} from './subtract'; import type {UnknownArray} from './unknown-array'; /** The implementation of `SplitArrayByIndex` for fixed length arrays. */ type SplitFixedArrayByIndex = SplitIndex extends 0 ? [[], T] : T extends readonly [...BuildTuple, ...infer V] ? T extends readonly [...infer U, ...V] ? [U, V] : [never, never] : [never, never]; /** The implementation of `SplitArrayByIndex` for variable length arrays. */ type SplitVariableArrayByIndex['length']>, T2 = T1 extends number ? BuildTuple[number]> : [], > = SplitIndex extends 0 ? [[], T] : GreaterThanOrEqual['length'], SplitIndex> extends true ? [ SplitFixedArrayByIndex, SplitIndex>[0], [ ...SplitFixedArrayByIndex, SplitIndex>[1], ...VariablePartOfArray, ], ] : [ [ ...StaticPartOfArray, ...(T2 extends UnknownArray ? T2 : []), ], VariablePartOfArray, ]; /** Split the given array `T` by the given `SplitIndex`. @example ``` type A = SplitArrayByIndex<[1, 2, 3, 4], 2>; // type A = [[1, 2], [3, 4]]; type B = SplitArrayByIndex<[1, 2, 3, 4], 0>; // type B = [[], [1, 2, 3, 4]]; ``` */ type SplitArrayByIndex = SplitIndex extends 0 ? [[], T] : number extends T['length'] ? SplitVariableArrayByIndex : SplitFixedArrayByIndex; /** Creates a new array type by adding or removing elements at a specified index range in the original array. Use-case: Replace or insert items in an array type. Like [`Array#splice()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) but for types. @example ``` type SomeMonths0 = ['January', 'April', 'June']; type Mouths0 = ArraySplice; //=> type Mouths0 = ['January', 'Feb', 'March', 'April', 'June']; type SomeMonths1 = ['January', 'April', 'June']; type Mouths1 = ArraySplice; //=> type Mouths1 = ['January', 'June']; type SomeMonths2 = ['January', 'Foo', 'April']; type Mouths2 = ArraySplice; //=> type Mouths2 = ['January', 'Feb', 'March', 'April']; ``` @category Array */ export type ArraySplice< T extends UnknownArray, Start extends number, DeleteCount extends number, Items extends UnknownArray = [], > = SplitArrayByIndex extends [infer U extends UnknownArray, infer V extends UnknownArray] ? SplitArrayByIndex extends [infer _Deleted extends UnknownArray, infer X extends UnknownArray] ? [...U, ...Items, ...X] : never // Should never happen : never; // Should never happen