UNPKG

type-plus

Version:
84 lines (79 loc) 1.98 kB
import type { IsAny } from '../any/any_type.js' import type { IsEqual } from '../equal/equal.js' import type { Abs } from '../math/abs.js' import type { GreaterThan } from '../math/greater_than.js' import type { Subtract } from '../math/subtract.js' import type { IsNever } from '../never/never_type.js' import type { StrictNumberType } from '../number/strict_number_type.js' import type { Integer } from '../numeric/integer.js' import type { Negative } from '../numeric/negative.js' /** * Gets the normalized index to access the element of an array or tuple. * * ```ts * type R = IndexAt<['a', 'b', 'c'], 2> // 2 * type R = IndexAt<['a', 'b', 'c'], -2> // 1 * * type R = IndexAt<['a', 'b', 'c'], 3> // never * type R = IndexAt<['a', 'b', 'c'], -4> // never * ``` */ export type IndexAt< A extends Array<unknown>, N extends number, Fail = never, Upper = A['length'], Lower = 0 > = IsNever<A, Fail, IndexAt._<A, N, Fail, Upper, Lower>> export namespace IndexAt { export type _< A extends Array<unknown>, N extends number, Fail = never, Upper = A['length'], Lower = 0 > = IsEqual< A['length'], 0, Fail, Integer< N, StrictNumberType< A['length'], // A: array N, // A: tuple Negative< N, GreaterThan<Abs<N>, A['length']> extends true ? Lower : Subtract<A['length'], Abs<N>>, GreaterThan<A['length'], N> extends true ? N : Upper > >, // N: number or float IsAny< N, number, StrictNumberType< N, // TODO: handle tuple to union of indexes N > > > > } /** * Is N an out of bound index of A. * * ```ts * type R = IsIndexOutOfBound<[1], 0> // false * type R = IsIndexOutOfBound<[1], -1> // false * type R = IsIndexOutOfBound<[1], 1> // true * type R = IsIndexOutOfBound<[1], -2> // true * ``` */ export type IsIndexOutOfBound<A extends unknown[], N extends number, Then = true, Else = false> = IsNever< IndexAt<A, N, never, never, never>, Then, Else >