FlattenDepth

Challenge

Recursively flatten array up to depth times.

For example:

type a = FlattenDepth<[1, 2, [3, 4], [[[5]]]], 2>; // [1, 2, 3, 4, [5]]. flattern 2 times
type b = FlattenDepth<[1, 2, [3, 4], [[[5]]]]>; // [1, 2, 3, 4, [[5]]]. Depth defaults to be 1

If the depth is provided, it’s guaranteed to be positive integer.

Solution

Zur Lösung dieses Problems können wir wieder variadic tuple types mit infer nutzen, um über jedes Element des Arrays zu laufen. Wichtig ist hierbei neben dem zweiten Typargument, welches wir mit 1 als Standard setzen, ein weiteres Typargument in Form eines Akkumulators zu definieren. Dieser hilft bei, die aktuelle Tiefe der Rekursion zu erfassen und diese dann zu beenden, sobald U der Länge des Akkumulators entspricht.

type FlattenDepth<
  T extends any[],
  // Maximale Tiefe, bis zu der entpackt wird
  U extends number = 1,
  // Akkumulator, um die aktuelle Tiefe zu speichern.
  D extends any[] = []
> = T extends [infer H, ...infer R]
  ? //
    D["length"] extends U
    ? T
    : H extends any[]
    ? // Entspricht H einem Array. so wird der Typ rekursiv erneut aufgerufen.
      [...FlattenDepth<H, U, [...D, 1]>, ...FlattenDepth<R, U, [...D]>]
    : [H, ...FlattenDepth<R, U, [...D]>]
  : [];

References