如何在TypeScript中通过扩展函数数组参数实现类型检查?
实现带类型检查的函数组合工具
需求是构建一个compose函数,它能接收一组插件函数(funcArray),并要求传入这些插件函数所需的所有参数;同时在添加插件函数时,能获得严格的类型检查,避免传入无效参数。
现有代码的问题
你当前的实现中,由于使用了any类型和不正确的泛型约束,导致compose函数无法对输入参数进行类型校验——比如可以随意传入多余的d: '2',也不会因为缺少插件必需参数而报错。
解决方案
通过自定义类型工具提取并合并插件函数的参数和返回值类型,实现严格的类型约束:
类型工具定义
// 提取单个函数的第一个参数类型 type ExtractFirstParam<F> = F extends (arg: infer P) => any ? P : never; // 合并函数数组中所有函数的第一个参数为交叉类型(确保所有参数都被满足) type MergeFuncParams<F extends readonly ((arg: any) => any)[]> = ExtractFirstParam<F[number]> extends infer P ? { [K in keyof P]: P[K] } : never; // 合并所有函数的返回值类型(用于推导compose的返回类型) type MergeFuncReturns<F extends readonly ((arg: any) => any)[]> = ReturnType<F[number]> extends infer R ? { [K in keyof R]: R[K] } : never;
带类型检查的compose函数实现
function compose<F extends readonly ((arg: any) => any)[]>( { funcArray, ...props }: { funcArray: F } & MergeFuncParams<F> ): { funcArray: F } & MergeFuncParams<F> & MergeFuncReturns<F> { return funcArray.reduce( (acc, func) => ({ ...acc, ...func(acc) }), { funcArray, ...props } as { funcArray: F } & MergeFuncParams<F> & MergeFuncReturns<F> ); }
测试示例
// 示例插件函数(修改为返回对象,方便结果合并) function func1({a, h} : { a: number, h: number}) { return { sum: a + h }; } function func2({b} : { b: string}) { return { wrapped: `__${b}__` }; } // ✅ 合法调用:传入所有必需参数 const result = compose({ funcArray: [func1, func2], a: 1, h: 2, b: 'test' }); // result的类型自动推导为:包含funcArray、所有输入参数、所有插件返回值的合并类型 console.log(result); // { funcArray: [...], a:1, h:2, b:'test', sum:3, wrapped: '__test__' } // ❌ 错误调用:缺少func1必需的h参数,TypeScript会直接报错 // const badResult = compose({ // funcArray: [func1, func2], // a: 1, // b: 'test' // }); // ❌ 错误调用:传入多余的d参数,TypeScript会直接报错 // const extraResult = compose({ // funcArray: [func1, func2], // a: 1, // h:2, // b: 'test', // d: '2' // });
核心逻辑说明
- 参数校验:
MergeFuncParams将所有插件函数的参数合并为交叉类型,要求compose的输入必须包含所有插件的必需参数,同时禁止传入未定义的多余参数。 - 返回类型推导:
MergeFuncReturns合并所有插件的返回值类型,让compose的返回结果类型包含所有插件输出的属性。 - 泛型约束:通过泛型
F约束funcArray的类型,确保添加插件函数时,TypeScript能自动校验函数的参数结构是否符合预期。
内容的提问来源于stack exchange,提问作者Yaroslav Prokopchuk
相关产品推荐
相关产品推荐

