/* eslint-disable @typescript-eslint/no-explicit-any */ // ref: https://zhuanlan.zhihu.com/p/38687656 /** Get the first element */ export type TupleHead = T[0] /** Remove the first element */ export type TupleTail = T extends [] ? [] : T extends [unknown] ? [] : T extends [unknown, ...infer U] ? U : unknown[] // export type TupleTail = ((...t: T) => void) extends (x: any, ...t: infer R) => void ? R : never export type TupleShift = TupleTail /** Get the last element */ export type TupleLast = T[TupleTail['length']] /** Remove the last element */ export type TupleRemoveLast = TypeAssert, T>, any[]> /** Insert element at first */ export type TupleUnshift = [X, ...T] // export type TupleUnshift = ((x: X, ...t: T) => void) extends (...t: infer R) => void ? R : never /** Append element at last */ export type TuplePush = [...T, X] /** Concat two tuples */ export type TupleConcat = [...A, ...B] // export type TupleConcat = { // 1: A, // 0: TupleConcat, TupleTail>, // }[B extends [] ? 1 : 0] // 用到的 helper 类型,简化代码和解决某些情况下的类型错误 export type TypeAssert = T extends A ? T : never // @ts-expect-error export type Overwrite = { [P in keyof T]: S[P] } /** * Whether literal type is in Tuple contains literal, * * @example ```ts * type Foo = isInType<['ab', 'cd'], 'ab'> * ``` * @returns boolean */ export type isInLiteralTuple = [Extract] extends [never] ? false : true export type TupleToUnion = T[number] export type Reverse = Reverse_ type Reverse_ = { 1: Result, 0: Reverse_, TupleUnshift>>, }[Tuple extends [] ? 1 : 0] export type FlattenNestedTuple = { [K in keyof T]: FlattenTuple } /** * Convert const type to type const input = [1, 2] as const * @example ```ts * const input = [1, [2, 3]] as const // note the `as const` * type Result = FlattenTuple // [1, 2 | 3] * ``` * */ type FlattenTuple = T extends readonly (infer U)[] ? U extends ((any)[]) ? TupleToUnion // ? U extends ((infer V)[]) // ? FlattenTuple | FlattenTuple : U : T