UNPKG

type-samurai

Version:

Advanced utility types for Typescript

82 lines (78 loc) 2.44 kB
import { IsEqual } from "./equal"; import { Abs, IfPositive, IsNegative, ParseNumber } from "./number"; import { IfGreaterOrEqual, IsGreaterOrEqual } from "./greater-than"; import { Sum } from "./sum"; import { Or } from "./or"; import { Push } from "./push"; import { IsEmptyArray } from "./array"; import { And } from "./and"; import { If } from "./if"; import { IsLowerThan } from "./lower-than"; import { IsArrayIndex } from "./is-array-index"; type SliceRemovedItemValue = Record<"__type-samurai_internal__", symbol>; type FilterRemoved< T extends readonly unknown[], Result extends unknown[] = [] > = T extends readonly [infer First, ...infer Rest extends unknown[]] ? FilterRemoved< Rest, First extends SliceRemovedItemValue ? Result : Push<Result, First> > : Result; /** * Type version of `Array.prototype.slice()` method. Returns a shallow copy of a portion of an array into a new array object selected from `start` to `end` (`end` not included) * @example * ```ts * // [2, 3] * type T0 = Slice<[1, 2, 3, 4], 1>; * // [2, 3] * type T1 = Slice<[1, 2, 3, 4], 1, 3>; * ``` */ type Slice< T extends readonly unknown[], Start extends number = 0, End extends number = T["length"] > = ( IsEmptyArray<T> extends true ? "self" : IsGreaterOrEqual<Start, T["length"]> extends true ? "empty" : IsNegative<End> extends true ? IsGreaterOrEqual<Abs<End>, T["length"]> extends true ? "empty" : [ IfPositive<Start, Start, Sum<T["length"], Start>>, Sum<T["length"], End> ] : And< Or<IsEqual<Start, 0>, IsGreaterOrEqual<Abs<Start>, T["length"]>>, IsGreaterOrEqual<End, T["length"]> > extends true ? "self" : [IfPositive<Start, Start, Sum<T["length"], Start>>, End] ) extends infer Indexes ? Indexes extends "self" ? T : Indexes extends "empty" ? [] : Indexes extends [ infer NewStart extends number, infer NewEnd extends number ] ? IfGreaterOrEqual<NewStart, NewEnd> extends true ? [] : FilterRemoved<{ [K in keyof T]: IsArrayIndex<K> extends true ? If< And< IsGreaterOrEqual<ParseNumber<K>, NewStart>, IsLowerThan<ParseNumber<K>, NewEnd> >, T[K], SliceRemovedItemValue > : T[K]; }> : T : T;