泛型场景下元组过滤递归中断的问题排查与修复
TypeScript类型推导问题:从ColumnDefinition元组生成目标对象类型
需求说明
我需要从定义好的columns元组类型,自动推导得到WANTED对象类型,相关代码如下:
declare class ColumnDefinition<T, R extends boolean = false, N extends string = string> { typeValidator: (v: unknown) => v is T; required: R; name: N; }; type columns = [ ColumnDefinition<number, true, 'ID'>, ColumnDefinition<string, true, 'text'>, ColumnDefinition<boolean, false, 'bool'>, ColumnDefinition<bigint, false, 'bigint'>, ]; type WANTED = { ID: number; text: string; bool?: boolean | undefined; bigint?: bigint | undefined; };
尝试的解决方案及问题
我尝试用递归元组过滤的方法实现,但递归部分出现类型异常,代码如下:
type FilterColumns< Required extends boolean, COLUMNS extends readonly ColumnDefinition<any, boolean, any>[], > = COLUMNS extends readonly [infer L, ...infer Rest] ? L extends ColumnDefinition<any, Required> ? [L, ...FilterColumns<Required, Rest>] : FilterColumns<Required, Rest> : [];
上述代码中,FilterColumns<Required, Rest>里的Rest被推断为unknown[],无法赋值给readonly ColumnDefinition<any, boolean, any>[]。请问为何Rest会被推断为unknown[]?该如何修复?
原因分析
TypeScript在处理泛型元组的解构推断时,即使COLUMNS被约束为readonly ColumnDefinition<any, boolean, any>[],当你使用COLUMNS extends readonly [infer L, ...infer Rest]语法时,解构后的剩余部分Rest并没有被自动继承原约束——泛型约束仅作用于完整的元组类型,剩余部分会 fallback 到最宽泛的unknown[]类型。
修复方案
方案一:修复递归过滤类型
在推断Rest时显式添加类型约束,让TypeScript明确剩余部分的类型:
type FilterColumns< Required extends boolean, COLUMNS extends readonly ColumnDefinition<any, boolean, any>[] > = COLUMNS extends readonly [infer L, ...infer Rest extends readonly ColumnDefinition<any, boolean, any>[]] ? L extends ColumnDefinition<any, Required> ? [L, ...FilterColumns<Required, Rest>] : FilterColumns<Required, Rest> : [];
方案二:直接生成目标对象类型(更高效)
其实不需要先过滤元组,可以直接通过映射类型一步生成WANTED类型,跳过中间过滤步骤:
type FromColumns<COLUMNS extends readonly ColumnDefinition<any, any, any>[]> = { [C in COLUMNS[number] as C['name']]: C extends ColumnDefinition<infer T, true, any> ? T : T | undefined; }; // 直接得到目标类型 type WANTED = FromColumns<columns>;
这个方案直接遍历元组中的每个ColumnDefinition,根据required字段决定属性是否可选,同时提取对应的类型T,完全满足需求。
内容的提问来源于stack exchange,提问作者Akxe
相关产品推荐
相关产品推荐

