TypeScript泛型:实现类型安全的函数与参数包装传递
TypeScript类型安全的函数包装器实现
我想在TypeScript里找一种类型安全的方式,把任意参数数量的函数和它的对应参数传给一个包装函数,期望的使用效果如下:
const myFunc1 = () => { /* ... */ }; wrapper(myFunc1); const myFunc2 = (a: string) => { /* ... */ }; wrapper(myFunc2, 'hello'); const myFunc3 = (a: string, b: number) => { /* ... */ }; wrapper(myFunc3, 'hello', 10);
我自己尝试了下面的写法,但没法保证类型安全:
function wrapper<A extends (...params: B[]) => any, B extends any>(x: A, ...y: B[]) {}
问题分析
你当前的泛型定义里,B 和函数 A 的参数类型没有强关联,导致传入的参数 y 可以是任意类型,完全没法和 x 的参数做类型匹配,达不到类型安全的目的。
正确实现方案
我们可以利用TypeScript的Parameters工具类型,或者直接在泛型中关联函数的参数类型元组,让包装函数的参数严格对应传入函数的参数类型:
function wrapper<F extends (...args: any[]) => any>(fn: F, ...args: Parameters<F>) { // 这里可以添加包装逻辑,比如执行函数并返回结果 return fn(...args); }
或者也可以手动定义参数类型元组的泛型,效果完全一致:
function wrapper<T extends any[], R>(fn: (...args: T) => R, ...args: T) { return fn(...args); }
效果验证
用上面的实现,当你传入不匹配的参数时,TypeScript会直接抛出类型错误:
// 错误:类型 'number' 的参数不能赋给类型 'string' 的参数 wrapper(myFunc2, 123); // 错误:应有 3 个参数,但获得 2 个 wrapper(myFunc3, 'hello');
这样就完全实现了类型安全的函数包装,保证传入的参数和目标函数的参数类型、数量完全匹配。
内容的提问来源于stack exchange,提问作者Ahmet Yazıcı
相关产品推荐
相关产品推荐

