type Pop<T extends any[]> = T extends [...infer _, infer Last] ? Last : [];
type RangeGen<T, R extends any[] = []> = R["length"] extends T
? R
: RangeGen<T, [...R, unknown]>;
type SubOne<T> =
RangeGen<T> extends [...infer First, infer _] ? First["length"] : 0;
type UnboxArray<T> = T extends (infer F)[] ? F : T;
type UnboxFunc<T> = T extends (...args: any) => infer R ? R : T;
type UnboxPromise<T> = T extends PromiseLike<infer R> ? R : T;
type Unwrap<T> = UnboxFunc<UnboxArray<UnboxPromise<T>>>;
type Unbox<T, L extends number = 0, R extends any[] = [T]> = [T] extends [
Unwrap<T>,
]
? Pop<R>
: L extends 0
? Unbox<Unwrap<T>, L, [...R, Unwrap<T>]>
: SubOne<L> extends 0
? Unwrap<T>
: Unbox<Unwrap<T>, SubOne<L>, [...R, Unwrap<T>]>;
Solution by ickynavigator #33903
type Unbox<T, Depth extends number = 0, C extends string = '0'>
= (Depth extends 0 ? '' : `${Depth}`) extends C ? T
: T extends Box<infer I> ? Unbox<I, Depth, PlusOne<C>>
: T
type Box<I> = (() => I) | I[] | PromiseLike<I>
type PlusOne<S>
= S extends `${infer L}9` ? L extends '' ? '10' : `${PlusOne<L>}0`
: S extends `${infer L}8` ? `${L}9` : S extends `${infer L}7` ? `${L}8` : S extends `${infer L}6` ? `${L}7` : S extends `${infer L}5` ? `${L}6` : S extends `${infer L}4` ? `${L}5` : S extends `${infer L}3` ? `${L}4` : S extends `${infer L}2` ? `${L}3` : S extends `${infer L}1` ? `${L}2` : S extends `${infer L}0` ? `${L}1` : '1'
Solution by teamchong #32987
type UnboxRec<T, D, C extends 1[]> = C['length'] extends D
? T
: T extends (readonly (infer I)[] | PromiseLike<infer I> | (() => infer I))
? UnboxRec<I, D, [...C, 1]>
: T;
type Unbox<T, D = 0> = UnboxRec<T, Exclude<D, 0>, []>;
Solution by alexandroppolus #32965
type Unbox<T, L extends number = 0, C extends number[] = []> =
C['length'] extends L
? L extends 0
? Unbox<T, L, [0]>
: T
: T extends ((...args: any[]) => infer R) | (infer R)[] | Promise<infer R>
? Unbox<R, L, [...C, 0]>
: T
Solution by XkSuperCool #32808
type SimpleUnbox<T> =
T extends (infer V)[] ? V :
T extends () => infer V ? V :
T extends Promise<infer V> ? V :
T;
type DeepUnbox<T, R = SimpleUnbox<T>> = T extends R ? T : DeepUnbox<R>;
type FakeArray<N extends number, T extends any[] = []> = T['length'] extends N ? T : FakeArray<N, [...T, any]>;
type Decrement<N extends number, A = FakeArray<N>> = A extends [any, ...infer T extends any[]] ? T['length'] : -1;
type Unbox<T, C extends number = -1> =
C extends -1 | 0 ? DeepUnbox<T> :
C extends 1 ? SimpleUnbox<T> :
Unbox<SimpleUnbox<T>, Decrement<C>>;
Solution by alexbidenko #32566
type Primitive = number | string | boolean
type Unbox<T, N extends number = 0, Cur extends 1[] = [1] >
= Cur['length'] extends N
? T extends () => infer R1 ? R1
: T extends (infer R2)[] ? R2
: T extends Promise<infer R3> ? R3
: T
: T extends () => infer R1 ? R1 extends Primitive ? R1 : Unbox<R1, N, [...Cur, 1]>
: T extends (infer R2)[] ? R2 extends Primitive ? R2 : Unbox<R2, N, [...Cur, 1]>
: T extends Promise<infer R3> ? R3 extends Primitive ? R3 : Unbox<R3, N, [...Cur, 1]>
: T
Solution by Heonys #32511
type Unbox<T, Depth = 0, Count extends any[] = [1]> = T extends ((...args: any[]) => infer R) | (infer R)[] | Promise<infer R>
? Count['length'] extends Depth ? R : Unbox<R, Depth, [...Count, 1]>
: T
Solution by Sun79 #32469
type Unbox<T, Deep extends number = 0, _DeepRecorder extends 1[] = []> =
Deep extends 0 ? Unbox<T, -1> : //To Infinity
_DeepRecorder[`length`] extends Deep ? T :
T extends Promise<infer R> ? Unbox<R, Deep, [..._DeepRecorder, 1]> :
T extends () => infer R ? Unbox<R, Deep, [..._DeepRecorder, 1]> :
T extends (infer R)[] ? Unbox<R, Deep, [..._DeepRecorder, 1]> :
T;
Solution by E-uler #32458