type FlattenDepth<T extends any[], S extends number = 1, U extends any[] = []> = U['length'] extends S
? T
: T extends [infer F, ...infer R]
? F extends any[]
? [...FlattenDepth<F, S, [...U, 1]>, ...FlattenDepth<R, S, U>]
: [F, ...FlattenDepth<R, S, U>]
: T;
Solution by wendao-liu #35059
type FlattenDepth<T, Number = 1, S extends number[] = []> = Number extends S['length'] ? T
: T extends [infer Pre, ...infer Next]
? Pre extends any[]
? [...FlattenDepth<Pre, Number, [...S, 1]>, ...FlattenDepth<Next, Number, S>]
: [Pre, ...FlattenDepth<Next, Number, S>]
: []
Solution by devshinthant #34960
先实现普通Flatten,由于普通Flatten本身会递归到完全展平为止,再添加一个递归深度条件让它拥有提前终止递归的能力即可。
type FlattenDepth<T, U extends number = 1> = U extends 0
? T
: T extends [infer First, ...infer Rest]
? First extends unknown[]
? [...FlattenDepth<First, MinusOne<U>>, ...FlattenDepth<Rest, U>]
: [First, ...FlattenDepth<Rest, U>]
: T
使用 2257 - MinusOne<T>
type Map = [9, 0, 1, 2, 3, 4, 5, 6, 7, 8]
type ReverseString<T extends string> = T extends `${infer First}${infer Rest}` ? `${ReverseString<Rest>}${First}` : T
type Decrease<T extends string> = T extends `${infer First extends number}${infer Rest}` ? `${Map[First]}${First extends 0 ? Decrease<Rest> : Rest}` : T
type ParseInt<T extends string> = T extends `${0}${infer Rest}` ? ParseInt<`${Rest}`> : (T extends `${infer N extends number}` ? N : 0)
type MinusOne<T extends number> = T extends 0 ? -1 : ParseInt<ReverseString<Decrease<ReverseString<`${T}`>>>>
Solution by 2083335157 #34897
// your answers
// 难点在于 deep层数
type FlattenDepth<T extends any[], D extends number = 1, U extends any[] = []> =
T extends [infer F, ...infer Rest] ?
F extends any[] ?
U['length'] extends D ?
[F, ...FlattenDepth<[...Rest], D, U>] :
[...FlattenDepth<F, D, [...U, 1]>, ...FlattenDepth<Rest, D, U>]
: [F, ...FlattenDepth<[...Rest], D, U>]
: T
Solution by Jayce-liang #34776
type FlattenOnce<T extends Array<any>> = T extends [infer F, ...infer Rest]
? F extends Array<any>
? [...F, ...FlattenOnce<Rest>]
: [F, ...FlattenOnce<Rest>]
: []
type FlattenDepth<T extends Array<any>, Depth = 1, DepthCount extends any[] = []> =
DepthCount["length"] extends Depth
? T
: FlattenDepth<FlattenOnce<T>, Depth, [...DepthCount, 'increment']>
Solution by maximallain #34775
type FlattenDepth<T extends any[], L extends number = 1, U extends any[] = []> = U['length'] extends L ? T :
T extends [infer V, ...infer rest] ?
V extends any[] ? [...FlattenDepth<V, L, [...U, 1]>, ...FlattenDepth<rest, L, U>] : [V, ...FlattenDepth<rest, L, U>]
: T
Solution by ouzexi #34063
// 你的答案
type FlattenDepth<T extends any[], N extends number = 1, L extends any[] = []> = T extends [infer H, ...infer R] ? H extends any[] ? L['length'] extends N ? [H, ...FlattenDepth<R, N, L>] : [...FlattenDepth<H, N, [true, ...L]>, ...FlattenDepth<R, N, L>]: [H, ...FlattenDepth<R, N, L>] : T;
Solution by HelloGGG #33557
type FlattenDepth<T extends any[], U extends number = 1, Q extends any[] = []> = T extends [
infer R,
...infer P,
]
? R extends any[]
? Q['length'] extends U
? [R, ...FlattenDepth<P, U>]
: [...FlattenDepth<[...R], U, [...Q, 1]>, ...FlattenDepth<P, U>]
: [R, ...FlattenDepth<P, U, [...Q]>]
: T;
Solution by Shaocang #31636
// your answers
type FlattenOne<T extends any[]> = T extends [infer F, ...infer R]
? F extends any[]
? [...F, ...FlattenOne<R>]
: [F, ...FlattenOne<R>]
: T;
type CheckFlat<T extends any[]> = T extends [infer F, ...infer R]
? F extends any[]
? false
: CheckFlat<R>
: true;
type FlattenDepth<
T extends any[],
N extends number = 1,
Rec extends any[] = []
> = CheckFlat<T> extends true
? T
: Rec["length"] extends N
? T
: FlattenDepth<FlattenOne<T>, N, [0, ...Rec]>;
Solution by chenqy-yh #31207
type FlattenDepth<T, D extends number = 1, U extends unknown[] = MakeNumberToArray<D>> = 0 extends U['length']
? T
: T extends [infer F, ...infer R]
? F extends unknown[]
? U extends [unknown, ...infer UR]
? [...FlattenDepth<F, D, UR>, ...FlattenDepth<R, D, U>]
: never
: [F, ...FlattenDepth<R, D, U>]
: T;
Solution by leejaehyup #30828
// your answers
type FlattenDepthOne<T extends any[]> =
T extends [infer F, ...infer Rest]
? F extends any[]
? [...F, ...FlattenDepthOne<Rest>]
: [F, ...FlattenDepthOne<Rest>]
: []
type CanFlatten<T> = T extends [infer F, ...infer Rest]
? F extends any[]
? true
: CanFlatten<Rest>
: false
type FlattenDepth<T extends any[], D=1, C extends number[] = []> =
C['length'] extends D
? T
: CanFlatten<T> extends true
? FlattenDepth<FlattenDepthOne<T>, D, [...C, 1]>
: T
Solution by enochjs #30481
type FlattenDepth<T extends unknown[], N extends number = 1, C extends number[] = []> = T extends [...infer A, infer B]
?
B extends Array<unknown>
?
C['length'] extends N
?
[...FlattenDepth<A, N, []>, B]
: FlattenDepth<[...A, ...B], N, [...C, 0]>
: [...FlattenDepth<A, N, []>, B]
: T
Solution by zhangqiangzgz #30176
The following solution makes use of MinusOne
:
type FlattenDepth<T extends any[], D extends number = 1> =
D extends 0 ? T :
T extends [infer F, ...infer R]
? F extends any[]
? [...FlattenDepth<F, MinusOne<D>>, ...FlattenDepth<R, D>]
: [F, ...FlattenDepth<R, D>]
: T
You can find my version of MinusOne
here: 2257 - MinusOne - Short solution with explanation.
But other solutions that use an auxiliary array for counting the depth (e.g. this one: 3243 - FlattenDepth #3364) are simpler and, as nesting depth requires only a very small number range, preferable.
Solution by sbr61 #30115
type FlattenOnce<T extends any[]> =
T extends [infer F, ...infer R] ?
[...F extends [...infer K] ?
K :
[F], ...FlattenOnce<R> ] :
T;
type FlattenDepth<T, Times extends number=1, P extends any[] = []> =
T extends any[] ?
P extends {length: Times} ?
T :
T extends FlattenOnce<T> ?
T :
FlattenDepth<FlattenOnce<T>, Times, [...P, any] > : never;
Solution by DmitriiBr #29567
type FlattenDepth<
T extends unknown[],
D extends number = 1,
S extends unknown[] = []
> = S["length"] extends D
? T
: T extends [infer F, ...infer Rest]
? F extends unknown[]
? [...FlattenDepth<F, D, [...S, number]>, ...FlattenDepth<Rest, D, S>]
: [F, ...FlattenDepth<Rest, D, S>]
: T;
Solution by DoubleWoodLin #28703
type ParseInt<T extends string> = T extends
${infer Num extends number} ? Num : T;
type RemoveLeadingZero<T extends string> = T extends
0${infer Str} ? Str extends "" ? "0" : RemoveLeadingZero<Str> : T;
type ReverseStr<T extends string> = T extends
${infer F}${infer R}?
${ReverseStr : T;
type InnerMinusOne<T extends string> = T extends
${infer F extends number}${infer R}? F extends 0 ?
9${InnerMinusOne:
${[9, 0, 1, 2, 3, 4, 5, 6, 7, 8][F]}${R} : T;
type MinusOne<T extends number> = ParseInt< RemoveLeadingZero<ReverseStr<InnerMinusOne<ReverseStr<
${T}`>>>>
;`
type FlattenDepth<T extends unknown[], D extends number = 1> = D extends 0 ? T : T extends [infer F, ...infer Rest] ? F extends unknown[] ? [...FlattenDepth<F, MinusOne<D>>, ...FlattenDepth<Rest, D>] : [F, ...FlattenDepth<Rest, D>] : T;
Solution by DoubleWoodLin #28702
// your answers
type FlattenDepth<
T extends any[],
S extends number = 1,
U extends any[] = []
> = U['length'] extends S
? T
: T extends [infer F, ...infer R]
? F extends any[]
? [...FlattenDepth<F, S, [...U, 1]>, ...FlattenDepth<R, S, U>]
: [F, ...FlattenDepth<R, S, U>]
: T
Solution by daiki-skm #28306
// your answers
type Check<T extends any[]> = T extends [infer F, ...infer Rest] ? F extends any[] ? true : Check<Rest> : false
type Flatten<T extends any[], R extends any[] = []> = T extends [infer F, ...infer Rest] ? F extends any[] ? Flatten<Rest, [...R, ...F]> : Flatten<Rest, [...R, F]> : R
type FlattenDepth<T extends any[], D extends number = 1, C extends any[] = []> =Check<T> extends true? D extends C['length'] ? T : FlattenDepth<Flatten<T>, D, [...C, any]>:T
Solution by AAA611 #27881
type FlattenOnce<T extends any[]> = T extends [infer F, ...infer R]
? F extends any[]
? [...F, ...FlattenOnce<R>]
: [F, ...FlattenOnce<R>]
: []
type IsFlatten<T extends any[]> = T extends [infer F, ...infer R]
? F extends any[]
? false
: IsFlatten<R>
: true
type FlattenDepth<T extends any[], U extends number = 1, S extends unknown[] = []> =
S['length'] extends U
? T
: IsFlatten<T> extends true
? T
: FlattenDepth<FlattenOnce<T>, U, [...S, unknown]>
Solution by jazelly #27857
type FlattenDepth<T, N extends number = 1, U extends any[] = []> = U['length'] extends N ?
T :
T extends [infer F, ...infer O] ?
F extends any[] ? [...FlattenDepth<F, N, [...U, 0]>, ...FlattenDepth<O, N, U>] :
[F, ...FlattenDepth<O, N, U>] : T
Solution by 8471919 #27831
type FlattenOnce<T extends any[], U extends any[] = []> T extends [infer L, ...infer R]
? L extends any[] ? FlattenOnce<R, [...U, ...L] : FlattenOnce<R, [...U, L]>
: U
type FlattenDepth<
T extends any[],
U extends number = 1,
P extends any[] = []
> = P['length'] extends U ? T
: FlattenOnce<T> extends T ? T
: FlattenDepth<FlattenOnce<T>, U, [...P, any]>
Solution by isntkyu #27773
type FlattenDepth<
A extends any[],
I extends number = 1,
_C extends number[] = []
> = I extends _C['length'] ? A :
A extends [infer First, ...infer Rest] ?
First extends any[] ?
[...FlattenDepth<First, I, [..._C, 0]>, ...FlattenDepth<Rest, I, _C>] :
[First, ...FlattenDepth<Rest, I, _C>]
: A;
Solution by jjswifty #27639
type FlattenDepth<
A extends unknown[],
Depth extends number = 1,
CountArr extends unknown[] = [],
Result extends unknown[] = []
> = CountArr["length"] extends Depth
? A
: A extends [infer First, ...infer Rest]
? First extends [...infer contents]
? FlattenDepth<
Rest,
Depth,
CountArr,
[...Result, ...FlattenDepth<contents, Depth, [...CountArr, 0]>]
>
: FlattenDepth<Rest, Depth, CountArr, [...Result, First]>
: Result;
Solution by alythobani #27542
type FlattenDepth<T, Number = 1, S extends number[] = []> = Number extends S['length'] ? T
: T extends [infer Pre, ...infer Next]
? Pre extends any[]
? [...FlattenDepth<Pre, Number, [...S, 1]>, ...FlattenDepth<Next, Number, S>]
: [Pre, ...FlattenDepth<Next, Number, S>]
: []
/
Solution by jiechliu #27452
type FlattenDepth<T extends unknown [], U extends number = 1, Counter extends unknown[] = [] > = U extends 1 ? FlattenOne<T> : T extends [infer F, ...infer R]
? F extends unknown[]
? Counter['length'] extends U
? [F, ...FlattenDepth<R, U, []>]
: [...FlattenDepth<F,U,[...Counter, 1]>, ...FlattenDepth<R,U,[]>]
: [F, ...FlattenDepth<R,U,[...Counter]>]
: []
Solution by nikitashevchenkodp #27104
type FlattenOnce<T> = T extends [infer F, ...(infer R)]
? [...(F extends any[] ? F : [F]), ...FlattenOnce<R>]
: T;
type FlattenDepth<
T,
N extends number = 1,
D extends any[] = []
> = T extends any[]
? D["length"] extends N
? T
: FlattenOnce<T> extends T
? T
: FlattenDepth<FlattenOnce<T>, N, [...D, ""]>
: T;
Solution by smileboyi #26968
type FlattenDepth<
T extends any[],
C extends number = 1,
U extends any[] = []
> = T extends [infer First,...infer Rest]
? First extends any[] // if First element is array
? U['length'] extends C // if flatten depth === C
? [First, ...FlattenDepth<Rest, C, U>]
: [
...FlattenDepth<First, C, [0,...U]>, // flatten First element for C-1 more times
...FlattenDepth<Rest, C, U> // and FlattenDepth<Rest, C>
]
: [First,...FlattenDepth<Rest, C, U>]
: T;
Solution by se030 #26945
type Flatten<T extends any[]> = T extends [ infer F, ...infer Rest] ? (F extends any[] ? [...F , ...Flatten<Rest> ] : [F, ...Flatten<Rest>]) : [];
type FlattenDepth<T extends any[], Depth = 1, A extends any[] = []> = A['length'] extends Depth ? T : FlattenDepth<Flatten<T>, Depth, [...A, '']>
Solution by jsujeong #26779
// your answers
type FlattenDepth<T, U extends number = 1, P extends any[] = [], A extends any[] = []> =
T extends any [] ?
T extends [infer L, ...infer R] ?
A['length'] extends U ? T : FlattenDepth<R, U, [...P, ...FlattenDepth<L, U, [], [...A, U]>]>
: P
: [T]
Solution by CheolMinBae #26777
type FlattenDepth<T extends unknown[], N extends number = 1, Acc extends unknown[] = []>
= T extends [infer F, ...infer Rest]
? F extends unknown[]
? Acc['length'] extends N
? [F, ...FlattenDepth<Rest, N, Acc>]
: [...FlattenDepth<F, N, [...Acc, never]>, ...FlattenDepth<Rest, N, Acc>]
: [F, ...FlattenDepth<Rest, N, Acc>]
: T
// error: Type instantiation is excessively deep and possibly infinite.
// type ToNumber<T extends unknown[]> = T['length']
// type ToArray<T extends number, Arr extends unknown[] = []> = ToNumber<Arr> extends T ? Arr : ToArray<T, [...Arr, undefined]>
// type Negative<T extends number> = `-${T}` extends `${infer V extends number}` ? V : never
// type Add<A extends number, B extends number> = ToNumber<[...ToArray<A>, ...ToArray<B>]>
// type Sub<A extends number, B extends number>
// = ToArray<A> extends [...ToArray<B>, ...infer Rest] ? ToNumber<Rest>
// : ToArray<B> extends [...ToArray<A>, ...infer Rest] ? Negative<ToNumber<Rest>>
// : never
// type MinusOne<N extends number> = Sub<N, 1>
// type FlattenOnce<T extends unknown[]> = T extends [infer F, ...infer Rest]
// ? F extends unknown[] ? [...F, ...FlattenOnce<Rest>] : [F, ...FlattenOnce<Rest>]
// : T
// type FlattenDepth<T extends unknown[], N extends number = 1>
// = N extends 0
// ? T
// : FlattenDepth<FlattenOnce<T>, MinusOne<N>>
Solution by tokyo9pm #26728