Skip to content

Chunk

约 584 字大约 2 分钟

2022-12-01

题目

Github: Chunk

你知道 lodash 吗?其中的 Chunk 是一个非常实用的函数,现在让我们来实现它。 Chunk<T, N> 接受两个必需的类型参数,T 必须是一个元组,而 N 必须是一个大于等于 1 的整数。

type exp1 = Chunk<[1, 2, 3], 2> // expected to be [[1, 2], [3]]
type exp2 = Chunk<[1, 2, 3], 4> // expected to be [[1, 2, 3]]
type exp3 = Chunk<[1, 2, 3], 1> // expected to be [[1], [2], [3]]

解题思路

首先我们从类型声明开始,类型 Chunk 接受三个参数 TNRT 是一个元组,N 是一个大于等于 1 的整数, R 是一个可选的参数,用于保存单个分块的结果。

type Chunk<
  T extends unknown[],
  N extends number,
  R extends unknown[] = []
> = any

对于单个分块 R,当其长度为 N 时,即满足 R['length'] extends N,则表示分块已经填满,需要继续填充下一个分块:

type Chunk<T extends unknown[], N extends number, R extends unknown[] = []> =
  R['length'] extends N ? [...R, Chunk<T, N>] : any

当分块未填满且数组 T 中还有元素时 T extends [infer F, ...infer U],需要继续分块:

type Chunk<T extends unknown[], N extends number, R extends unknown[] = []> =
  R['length'] extends N
    ? [...R, Chunk<T, N>]
    : T extends [infer F, ...infer U]
      ? Chunk<U, N, [...R, F]>
      : any

也要考虑,当数组 T 已清空时,如果 R 中还有元素,需要将 [R] 返回,否则返回 []

答案

type Chunk<
  T extends unknown[],
  N extends number,
  R extends unknown[] = []
> = R['length'] extends N
  ? [R, ...Chunk<T, N>]
  : T extends [infer F, ...infer U]
    ? Chunk<U, N, [...R, F]>
    : R extends [] ? [] : [R]

验证

type 
cases
= [
Expect
<
Equal
<
Chunk
<[], 1>, []>>,
Expect
<
Equal
<
Chunk
<[1, 2, 3], 1>, [[1], [2], [3]]>>,
Expect
<
Equal
<
Chunk
<[1, 2, 3], 2>, [[1, 2], [3]]>>,
Expect
<
Equal
<
Chunk
<[1, 2, 3, 4], 2>, [[1, 2], [3, 4]]>>,
Expect
<
Equal
<
Chunk
<[1, 2, 3, 4], 5>, [[1, 2, 3, 4]]>>,
Expect
<
Equal
<
Chunk
<[1, true, 2, false], 2>, [[1, true], [2, false]]>>,
]

参考