ghaiklor / type-challenges-solutions

Solutions for the collection of TypeScript type challenges with explanations
https://ghaiklor.github.io/type-challenges-solutions/
Creative Commons Attribution 4.0 International
471 stars 56 forks source link

type-challenges-solutions/en/medium-flatten #314

Open utterances-bot opened 1 year ago

utterances-bot commented 1 year ago

Flatten

This project is aimed at helping you better understand how the type system works, writing your own utilities, or just having fun with the challenges.

https://ghaiklor.github.io/type-challenges-solutions/en/medium-flatten.html

MajorLift commented 1 year ago

There are two issues with this solution:

Given the following test case...

// @ts-expect-error
type error = Flatten<undefined>
albert-luta commented 1 year ago

My solution is similar with @MajorLift one, except I'm using Flattern 1 instantiation less :P

type Flatten<T extends unknown[]> = T extends [infer Head, ...infer Tail]
  ? Head extends unknown[]
    ? Flatten<[...Head, ...Tail]>
    : [Head, ...Flatten<Tail>]
  : [];
MajorLift commented 1 year ago

@albert-luta Nice! It seems that your solution would result in less optimal recursion depth, as the Flatten call will attempt to process the entire input array (with Head one level flattened) on a single stack. Depending on how deeply nested the elements of T are, this could result in a significant performance hit.

okadurin commented 1 year ago

I believe this initial example could be improved

type Flatten<T> = T extends []
  ? []
  : T extends [infer H, ...infer T]
  ? [H, T]
  : [T];
JanessaTech commented 4 weeks ago

My solution using acc to trace the result while in recursion

  type Flatten<T extends unknown[], acc extends unknown[] = []> = T extends [infer F, ...infer R]
  ? F extends unknown[]
    ? Flatten<R, [...acc, ...Flatten<F, []>]>
    : Flatten<R, [...acc, F]>
  : acc