1. case说明及解释
type A = Filter<[1,'BFE', 2, true, 'dev'], number> // [1, 2]
type B = Filter<[1,'BFE', 2, true, 'dev'], string> // ['BFE', 'dev']
type C = Filter<[1,'BFE', 2, any, 'dev'], string> // ['BFE', any, 'dev']
2.伪代码
type Filter<T extends any[], A, R extends any[] = []> = T extends
[infer F, ...infer Rest] ?
F extends A
? Filter<Rest, A, [...R, F]>
: Filter<Rest, A, R>
: R;
无法过测试案例中any
type C = Filter<[1, 'BFE', 2, any, 'dev'], string> // ['BFE', any, 'dev']
伪代码version0.1
//加个any判断不就好了
type Filter<T extends any[], A, R extends any[] = []> = T extends
[infer F, ...infer Rest] ?
F extends A | any
? Filter<Rest, A, [...R, F]>
: Filter<Rest, A, R>
: R;
还是不行,后面无法过测试用例,但是写的思路如下
Filter<T extends any[], A, R extends any[] = []>:定义一个名为Filter的泛型类型,它接受三个类型参数,分别为待过滤元组T、要筛选的类型A和结果元组R。R的默认值为[]。T extends [infer F, ...infer Rest]:检查待过滤元组T是否非空。如果非空,使用类型推断来获取第一个元素F和剩余元素Rest。F extends A:检查元素F是否是类型A。如果是,则将其添加到结果元组R中,并继续递归处理剩余元素Rest。否则,跳过当前元素,仅处理剩余元素Rest。R:如果待过滤元组T为空,则表示已处理完所有元素。返回结果元组R。
3.解决答案
type Filter<T extends any[], A, R extends A[] = []> =
T extends [infer F, ...infer O]
? [F] extends [A]
? Filter<O, A, [...R, F]>
: Filter<O, A, R>
: R
思路解释
Filter<T extends any[], A, R extends A[] = []>:定义一个名为Filter的泛型类型,它接受三个类型参数,分别为待过滤元组T、要筛选的类型A和结果元组R。R的默认值为[]。注意,这里我们限制了R只能包含类型A的元素。T extends [infer F, ...infer O]:检查待过滤元组T是否非空。如果非空,使用类型推断来获取第一个元素F和剩余元素O。[F] extends [A]:这是一个类型检查,用于判断元素F是否是类型A。将F和A分别包装在元组中,然后利用元组的逐项类型检查。这样做的原因是,当涉及到泛型类型(如A)时,直接使用F extends A可能会导致预期之外的结果。包装在元组中可以更精确地进行类型检查。- 如果类型检查结果为
true,说明元素F是类型A,则将其添加到结果元组R中,并继续递归处理剩余元素O。否则,跳过当前元素,仅处理剩余元素O。 R:如果待过滤元组T为空,则表示已处理完所有元素。返回结果元组R。