import { Extends, Or } from './Boolean'; import { Add, Decrement, Enumerate, Increment, IsGreaterThan, Subtract } from './Number'; import { NoUncheckedIndexedAccess } from './compilerOptions'; import { Keys } from './misc'; import { Flatten } from 'ts-toolbelt/out/List/Flatten'; import { Head } from 'ts-toolbelt/out/List/Head'; import { Tail } from 'ts-toolbelt/out/List/Tail'; import { Take } from 'ts-toolbelt/out/List/Take'; import { Length } from 'ts-toolbelt/out/String/Length'; import { ListOf } from 'ts-toolbelt/out/Union/ListOf'; type _BuildPowersOf2LengthArrays = AccumulatedArray[0][Length] extends never ? AccumulatedArray : _BuildPowersOf2LengthArrays; type _ConcatLargestUntilDone = NextArray['length'] extends Length ? NextArray : _ConcatLargestUntilDone; type _Replace = { [K in keyof R]: T; }; /** * creates an array with a fixed length * @example * TupleOf //[number, number, number, number] * @see https://github.com/microsoft/TypeScript/issues/26223#issuecomment-674514787 */ export type TupleOf = number extends Length ? Type[] : { [LengthKey in Length]: _BuildPowersOf2LengthArrays extends infer TwoDimensionalArray ? TwoDimensionalArray extends never[][] ? _Replace<_ConcatLargestUntilDone, Type> : never : never; }[Length]; /** * an array that can be of any length between 0 and `L` * @example * declare const foo: TupleOfUpTo * foo[0] //number (or number|undefined if `noUncheckedIndexedAccess` is enabled) * foo[3] //error: tuple of length '3' has no element at index '3' */ export type TupleOfUpTo = TupleOf>>; /** * an array of length `L` - 1 * @example * declare const foo: TupleOfExcluding * foo[1] //number * foo[2] //error: tuple of length '2' has no element at index '2' */ export type TupleOfExcluding = TupleOf>; /** * an array that can be of any length between 0 and `L`, excluding `L` * @example * declare const foo: TupleOfUpToButNotIncluding * foo[1] //number (or number|undefined if `noUncheckedIndexedAccess` is enabled) * foo[2] //error: tuple of length '2' has no element at index '2' */ export type TupleOfUpToButNotIncluding = TupleOfExcluding | (NoUncheckedIndexedAccess extends true ? [] : never); /** * an array that has a size of at least `Length` */ export type TupleOfAtLeast = TupleOf | Type[]; /** * like `keyof` but for array indexes, and uses numbers instead of strings */ export type Index = Enumerate; type _IndexOf> = Array[CurrentIndex] extends Value ? CurrentIndex : CurrentIndex extends Array['length'] ? -1 : _IndexOf>; /** * the type equivalent of {@link Array.prototype.indexOf} */ export type IndexOf = number extends Array['length'] ? number : { [Key in Keys>]: _IndexOf[Key], 0>; }[Keys>]; /** * creates a tuple type of alternating types * @example * type Foo = FlattenedTupleOf<[string, number], 3> //[string, number, string, number, string, number] */ export type FlattenedTupleOf = Flatten>; export type LengthGreaterThan = IsGreaterThan; /** removes `DeleteCount` values from `Array` starting at `StartIndex` */ export type Splice, InsertItems extends readonly unknown[] = []> = [...Take, ...InsertItems, ...Take, '<-'>]; /** removes the value at index `RemoveIndex` from `Array` */ export type RemoveIndex> = Splice; type _IndexOfLongestString = Strings[CurrentIndex] extends undefined ? CurrentLongestIndex : _IndexOfLongestString, IsGreaterThan, Length> extends true ? CurrentIndex : CurrentLongestIndex>; /** * gets the index of the longest string type in an array of strings * @example * type Foo = IndexOfLongestString<['foo', 'barbaz', 'qux']> //1 */ export type IndexOfLongestString = Strings extends [] ? undefined : number extends Strings['length'] ? number : _IndexOfLongestString; type SortLongestStringsTailRec = Or> | Extends> extends true ? [...Result, ...Array] : SortLongestStringsTailRec>, [ ...Result, Array[IndexOfLongestString] ]>; /** sorts an array of strings by longest to shortest */ export type SortLongestStrings = SortLongestStringsTailRec; type _IndexOfHighestNumber = CurrentIndex extends Numbers['length'] ? CurrentHighestNumberIndex : _IndexOfHighestNumber, IsGreaterThan extends true ? CurrentIndex : CurrentHighestNumberIndex>; /** gets the index of the largest number in an array type */ export type IndexOfHighestNumber = _IndexOfHighestNumber; export type RemoveValueTailRec = Array extends [] ? Result : RemoveValueTailRec, Value, [ ...Result, ...(Head extends Value ? [] : [Head]) ]>; /** * removes types from `Array` that match type `Value` * @example * type Foo: RemoveValue<['foo', 'bar', 'baz'], 'bar'> //['foo', 'baz'] */ export type RemoveValue = RemoveValueTailRec; type SliceCount = StartCount extends Start ? EndCount extends PositionFromEnd ? Array : Array extends readonly [...infer Rest, unknown] ? SliceCount> : [] : Array extends readonly [unknown, ...infer Rest] ? SliceCount, EndCount> : Array; type GetPositionFromEnd = Subtract; /** * compiletime version of {@link Array.slice} */ export type Slice = number extends Start | End ? Array[number][] : GetPositionFromEnd extends never ? Array[number][] : SliceCount, 0, 0>; /** compiletime version of {@link _.castArray} */ export type CastArray = T extends readonly unknown[] ? T : [T]; /** * an array with a specified `Dimension` */ export type DimensionArray = (T | (Dimension extends 0 ? never : DimensionArray>))[]; /** * for some reason the ts toolbelt Tail causes a recursion error in the {@link EveryCombination} * types so i made this one instead */ type Tail2 = number extends T['length'] ? never : Splice; type InsertIntoEachIndexInArray = number extends T['length'] ? never : [ Splice, ...(Count extends T['length'] ? [] : InsertIntoEachIndexInArray>) ]; type AddToCombinations = T extends [] ? [] : [ ...InsertIntoEachIndexInArray, ...(Tail2 extends infer Narrowed extends unknown[][] ? AddToCombinations : never) ]; type _EveryCombination = T extends [] ? [] : T extends [unknown] ? Result : AddToCombinations extends infer Narrowed extends unknown[][] ? _EveryCombination, Narrowed> : never; /** * creates a union type of every possible combination of values in the `T` array type, excluding * duplicates. * * if you want to allow duplicates, do something like `TupleOf` */ export type EveryCombination = _EveryCombination extends infer Result ? Result[number & keyof Result] : never; export {}; //# sourceMappingURL=Array.d.ts.map