在TypeScript中包装函数扩展自定义参数遇类型错误,求正确实现
修正后的代码
const func = (a: string) => { console.log(a); } type Options = { force?: boolean }; const wrapFunc = <A extends any[], R>(fn: (...args: A) => R) => { const wrappedFunc = (...args: [...A, options?: Options]) => { const lastArg = args[args.length - 1]; const options: Options = typeof lastArg === 'object' && lastArg !== null && 'force' in lastArg ? args.pop() as Options : {}; fn(...args as A); } return wrappedFunc; } const newFunc = wrapFunc(func); newFunc('a', {force: true}); // 正常工作 newFunc('a'); // 支持不传options参数
关键修正说明
- 参数类型调整:将原类型
A & [options?: Options]改为[...A, options?: Options]。前者是交集类型,要求参数同时满足原函数参数数组和带可选Options的数组,会导致长度冲突;后者是扩展元组类型,表示原参数数组后可追加一个可选的Options参数,完全匹配我们扩展参数的需求。 - 优化参数判断逻辑:原代码仅通过
'force' in args[args.length - 1]判断最后一个参数是否为Options,若最后一个参数是不含force的普通对象会误判。新增typeof lastArg === 'object' && lastArg !== null的前置判断,避免非对象类型引发的错误。 - 明确类型断言:通过
args.pop() as Options和args as A帮助TypeScript确认类型合法性,因为执行pop操作后,args的长度已完全匹配原函数的参数数组A。
内容的提问来源于stack exchange,提问作者Anton Liam
相关产品推荐
相关产品推荐

