type Unbox<T, Depth extends number = 0, Count extends '🍌'[] = Depth extends 0 ? never : []> =
Depth extends Count['length']
? T
: T extends Box<infer I>
? Unbox<I, Depth, [...Count, '🍌']>
: T;
type Box<I> = (() => I) | I[] | Promise<I>;
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