Advanced TypeScript Exercises - Answer 6

Pragmatic Maciej - Mar 8 '20 - - Dev Community

6.1 Naive version (lower difficulty)

type NaiveFlat<T extends any[]> = {
  [K in keyof T]: T[K] extends any[] ? T[K][number] : T[K]
}[number];
Enter fullscreen mode Exit fullscreen mode

The solution of naive version is mapped type which traverse through type T given as argument. Important parts:

  • T[K] extends any[] - question if value type of property K is an array
  • T[K] extends any[] ? T[K][number] : T[K] - if T[K] is an array we get its value type by indexed type [number]. number is correct key of T[K] as T[K] was checked before for being an array, and array has number keys
  • [number] at the end has a purpose of getting all value types of produced type

6.2 Deep version (higher difficulty)

type DeepFlat<T extends any[]> = {
  [K in keyof T]: T[K] extends any[] ? DeepFlat<T[K]> : T[K]
}[number]
Enter fullscreen mode Exit fullscreen mode

The solution of deep version is different only in one point, instead of T[K][number] we go further and call DeepFlat<T[K]> so its recursive type, it calls itself. Thanks to the recursive nature we traverse the object until value type is not an array what is visible in "else" part : T[K]

The full code with test suite can be found in The Playground

This series will continue. If you want to know about new exciting questions from advanced TypeScript please follow me on dev.to and twitter.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player