Fill
约 695 字大约 2 分钟
2022-12-01
题目
Github: Fill
Fill,一个常见的JavaScript函数,现在让我们用类型来实现它。 Fill<T, N, Start?, End?>,如你所见,Fill 接受四种类型的参数,其中 T 和 N 是必需参数, 而 Start 和 End 是可选参数。 这些参数的要求是:T 必须是元组,N 可以是任何类型的值,Start 和 End 必须是大于或等于 0 的整数。
type exp = Fill<[1, 2, 3], 0> // expected to be [0, 0, 0]解题思路
首先,我们从类型声明开始,类型 Fill 接受五个参数 T,N,Start,End,Count,Flag, T 是一个元组,N 可以是任何类型的值, Start 和 End 必须是大于或等于 0 的整数。
通过 Count 数组隐式追踪索引:
- 在
Count等于End的时候需要结束替换,也就是结束条件 - 当
Count等于Start的时候是开始替换的条件,递归处理数组替换即可,注意需要把T换成新的
使用 Flag 标记当前是否需要替换:
- 通过
Flag的默认值Count['length'] extends Start ? true : false智能触发状态切换。 - 仅在未显式传递
Flag时 重新计算状态,实现状态锁存:- 当第一次进入填充区间时,
Flag被设置为true - 后续递归中显式传递
Flag参数,保持状态不变
- 当第一次进入填充区间时,
Count['length'] extends End 作为终止条件
剩余元素直接保留原样,确保处理效率
答案
type Fill<
T extends unknown[],
N,
Start extends number = 0,
End extends number = T['length'],
Count extends any[] = [],
Flag extends boolean = Count['length'] extends Start ? true : false
> =
Count['length'] extends End
? T
: T extends [infer R, ...infer U]
? Flag extends false
? [R, ...Fill<U, N, Start, End, [...Count, 0]>]
: [N, ...Fill<U, N, Start, End, [...Count, 0], Flag>]
: T验证
type cases = [
Expect<Equal<Fill<[], 0>, []>>,
Expect<Equal<Fill<[], 0, 0, 3>, []>>,
Expect<Equal<Fill<[1, 2, 3], 0, 0, 0>, [1, 2, 3]>>,
Expect<Equal<Fill<[1, 2, 3], 0, 2, 2>, [1, 2, 3]>>,
Expect<Equal<Fill<[1, 2, 3], 0>, [0, 0, 0]>>,
Expect<Equal<Fill<[1, 2, 3], true>, [true, true, true]>>,
Expect<Equal<Fill<[1, 2, 3], true, 0, 1>, [true, 2, 3]>>,
Expect<Equal<Fill<[1, 2, 3], true, 1, 3>, [1, true, true]>>,
Expect<Equal<Fill<[1, 2, 3], true, 10, 0>, [1, 2, 3]>>,
Expect<Equal<Fill<[1, 2, 3], true, 10, 20>, [1, 2, 3]>>,
Expect<Equal<Fill<[1, 2, 3], true, 0, 10>, [true, true, true]>>,
]