如何为函数处理器结果的泛型聚合定义TypeScript类型?
TypeScript 链式处理器的类型推导方案
问题场景
需要实现一个configure生成器函数,通过链式添加处理器(processor)合并配置结果,要求TypeScript自动推导done()返回值的类型——即默认处理器返回的BaseConfig与所有后续添加的处理器返回类型的交集。原示例代码及使用方式如下:
原实现代码
function configure() { // 内部复杂嵌套配置 const config = { root: true, basic: true, value: 10, }; const processors = [ // 默认处理器,返回BaseConfig function(data) { return { isRoot: data.root, isBasic: data.basic, value: data.value * 5 }; } ]; return { addProcessor(handler) { // 需要为该方法定义类型 processors.push(handler); return this; }, done() { // 返回类型应为BaseConfig & 所有处理器返回类型的交集 return Object.assign({}, ...processors.map((p) => p(config))); } } }
使用方式
const res = configure() .addProcessor(function(data) { return { isBasic: false, value: data.value * 10, } }) .done(); // 期望res类型自动推导为 { isRoot: boolean; isBasic: boolean; value: number; } // 实际值为 { isRoot: true, isBasic: false, value: 100 }
核心需求:无法提前预知后续处理器的返回类型,需通过泛型链式跟踪所有类型,最终合并为交叉类型。
解决方案
通过泛型对象类型跟踪处理器的返回类型集合,结合TypeScript的ReturnType工具类型和交叉类型实现自动合并。
完整实现代码
// 定义输入配置的固定类型 type InputConfig = { root: boolean; basic: boolean; value: number; }; // 提取默认处理器并推导其返回类型 const defaultProcessor = (data: InputConfig) => ({ isRoot: data.root, isBasic: data.basic, value: data.value * 5 }); type BaseConfig = ReturnType<typeof defaultProcessor>; // 泛型生成器类型,T用于累积所有扩展处理器的返回类型交叉 type ConfigureGenerator<T = {}> = { addProcessor<U>(handler: (data: InputConfig) => U): ConfigureGenerator<T & U>; done(): BaseConfig & T; }; function configure(): ConfigureGenerator { const config: InputConfig = { root: true, basic: true, value: 10, }; const processors: ((data: InputConfig) => unknown)[] = [defaultProcessor]; return { addProcessor(handler) { processors.push(handler); // 类型断言修正链式调用的泛型跟踪 return this as unknown as ConfigureGenerator< BaseConfig & ReturnType<typeof handler> >; }, done() { return Object.assign({}, ...processors.map(p => p(config))) as BaseConfig & ReturnType<typeof processors[number]>; } }; }
关键细节说明
泛型链式跟踪:
ConfigureGenerator<T>中的T用于累积每次addProcessor添加的处理器返回类型交叉。每次调用addProcessor<U>,都会返回新的ConfigureGenerator<T & U>,实现类型的链式累积。自动类型提取与合并:
- 用
ReturnType<typeof handler>自动提取处理器的返回类型,无需手动声明。 done()的返回类型为BaseConfig & T,自动合并默认类型与所有扩展类型,重复属性的类型会按交叉规则自动覆盖。
- 用
类型断言的作用:
由于JS中this的运行时特性,TypeScript无法自动推导链式调用中this的泛型变化,因此需要用类型断言手动修正类型。
使用验证
const res = configure() .addProcessor(data => ({ isBasic: false, value: data.value * 10, extraProp: "hello" })) .addProcessor(data => ({ isRoot: false, anotherProp: 123 })) .done(); // 自动推导res类型为: // { isRoot: boolean; isBasic: boolean; value: number; extraProp: string; anotherProp: number; }
内容的提问来源于stack exchange,提问作者Andrey Popov
相关产品推荐
相关产品推荐

