UNPKG

type-fest

Version:

A collection of essential TypeScript types

115 lines (86 loc) 3.28 kB
import type {If} from './if.d.ts'; import type {IfNotAnyOrNever} from './internal/type.d.ts'; import type {IsNegative} from './numeric.d.ts'; import type {DigitCharacter} from './characters.d.ts'; import type {UnknownArray} from './unknown-array.d.ts'; /** Create a tuple type of the specified length with elements of the specified type. @example ``` import type {TupleOf} from 'type-fest'; type RGB = TupleOf<3, number>; //=> [number, number, number] type Line = TupleOf<2, {x: number; y: number}>; //=> [{x: number; y: number}, {x: number; y: number}] type TicTacToeBoard = TupleOf<3, TupleOf<3, 'X' | 'O' | null>>; //=> [['X' | 'O' | null, 'X' | 'O' | null, 'X' | 'O' | null], ['X' | 'O' | null, 'X' | 'O' | null, 'X' | 'O' | null], ['X' | 'O' | null, 'X' | 'O' | null, 'X' | 'O' | null]] ``` @example ``` import type {TupleOf} from 'type-fest'; type Range<Start extends number, End extends number> = Exclude<keyof TupleOf<End>, keyof TupleOf<Start>>; type ZeroToFour = Range<0, 5>; //=> '0' | '1' | '2' | '3' | '4' type ThreeToEight = Range<3, 9>; //=> '3' | '4' | '5' | '6' | '7' | '8' ``` Note: If the specified length is the non-literal `number` type, the result will not be a tuple but a regular array. @example ``` import type {TupleOf} from 'type-fest'; type StringArray = TupleOf<number, string>; //=> string[] ``` Note: If the type for elements is not specified, it will default to `unknown`. @example ``` import type {TupleOf} from 'type-fest'; type UnknownTriplet = TupleOf<3>; //=> [unknown, unknown, unknown] ``` Note: If the specified length is negative, the result will be an empty tuple. @example ``` import type {TupleOf} from 'type-fest'; type EmptyTuple = TupleOf<-3, string>; //=> [] ``` Note: If the specified length has a decimal part, the decimal part will be ignored. @example ``` import type {TupleOf} from 'type-fest'; type DecimalLength = TupleOf<3.5, string>; //=> [string, string, string] ``` Note: If you need a readonly tuple, simply wrap this type with `Readonly`, for example, to create `readonly [number, number, number]` use `Readonly<TupleOf<3, number>>`. @category Array */ export type TupleOf<Length extends number, Fill = unknown> = IfNotAnyOrNever<Length, { ifNot: _TupleOf<If<IsNegative<Length>, 0, Length>, Fill>; ifAny: Fill[]; ifNever: []; }>; type _TupleOf<Length extends number, Fill> = number extends Length ? Fill[] : BuildTupleDigitByDigit<`${Length}`, Fill>; type BuildTupleDigitByDigit<Length extends string, Fill, Accumulator extends UnknownArray = []> = Length extends `${infer First extends DigitCharacter}${infer Rest}` ? BuildTupleDigitByDigit<Rest, Fill, [...RepeatTupleTenTimes<Accumulator>, ...DigitTupleOf<First, Fill>]> : Accumulator; type RepeatTupleTenTimes<Tuple extends UnknownArray> = [ ...Tuple, ...Tuple, ...Tuple, ...Tuple, ...Tuple, ...Tuple, ...Tuple, ...Tuple, ...Tuple, ...Tuple, ]; type DigitTupleOf<Digit extends DigitCharacter, Fill> = [ [], [Fill], [Fill, Fill], [Fill, Fill, Fill], [Fill, Fill, Fill, Fill], [Fill, Fill, Fill, Fill, Fill], [Fill, Fill, Fill, Fill, Fill, Fill], [Fill, Fill, Fill, Fill, Fill, Fill, Fill], [Fill, Fill, Fill, Fill, Fill, Fill, Fill, Fill], [Fill, Fill, Fill, Fill, Fill, Fill, Fill, Fill, Fill], ][Digit]; export {};