type-challenges:Flatten

49 阅读1分钟

Flatten

问题描述

在这个挑战中,你需要写一个接受数组的类型,并且返回扁平化的数组类型。

例如:

type flatten = Flatten<[1, 2, [3, 4], [[[5]]]]> // [1, 2, 3, 4, 5]
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'type cases = [
  Expect<Equal<Flatten<[]>, []>>,
  Expect<Equal<Flatten<[1, 2, 3, 4]>, [1, 2, 3, 4]>>,
  Expect<Equal<Flatten<[1, [2]]>, [1, 2]>>,
  Expect<Equal<Flatten<[1, 2, [3, 4], [[[5]]]]>, [1, 2, 3, 4, 5]>>,
  Expect<Equal<Flatten<[{ foo: 'bar'; 2: 10 }, 'foobar']>, [{ foo: 'bar'; 2: 10 }, 'foobar']>>
]
​
// @ts-expect-error
type error = Flatten<'1'>
// ============= Your Code Here =============
// 答案
type Flatten<T extends any[], All extends any[] = []> = T extends [infer F, ...infer R]
  ? F extends any[]
    ? Flatten<[...F,...R], All>
    : Flatten<R, [...All, F]>
  : All

仔细观察会发现,这道题和上一道 Length of String 十分相似,首先,都是一项一项取,并且需要用到递归,第二,肯定需要一个用于存放修改后的数组的泛型,所以需要添加第二个参数,这里的逻辑是,首先使用 infer 关键字一个一个的取出第一项,其次需要进行判断,当前这一项是不是数组,不是数组,那么将它保存在泛型的第二个参数 All 中,如果是数组,那么继续将它解构后递归调用此类型判断这一项是不是数组,最后返回整个铺平后的数组。