Chunk
题目
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
接受三个参数 T
,N
,R
,T
是一个元组,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]]>>,
]