TypeScript:能否从前置参数推断回调最后一个参数的类型?
解决方案
你的问题核心在于当前泛型结构无法让TypeScript协同推断defaults的类型与回调函数最后一个参数的类型。可以通过调整泛型参数的定义顺序和约束逻辑来解决:
修改后的实现代码
export type WithDefaultOptions<Options extends object, Args extends any[], Ret> = (...args: [...Args, Partial<Options>?]) => Ret; export function withDefaultOptions<Options extends object, Args extends any[], Ret>( defaults: Options, callback: (...args: [...Args, Options]) => Ret ): WithDefaultOptions<Options, Args, Ret> { return ((...args) => { const lastArg = args[args.length - 1]; // 区分最后一个参数是否是options(处理没有传options的情况) const hasProvidedOptions = typeof lastArg === 'object' && lastArg !== null; const resolvedArgs = hasProvidedOptions ? [...args.slice(0, -1), { ...defaults, ...lastArg }] : [...args, defaults]; return callback(...resolvedArgs as [...Args, Options]); }) as WithDefaultOptions<Options, Args, Ret>; }
关键改进说明
- 拆分泛型参数:将原有的
Callback泛型拆分为Args(回调前置参数列表)和Ret(返回值类型),让Options优先从defaults参数推断,再绑定到回调的最后一个参数。 - 完善参数处理逻辑:新增判断逻辑,处理调用时未传入options参数的场景(此时直接使用默认值)。
示例验证
const split = withDefaultOptions( { max: 0 }, (s: string, options) => { // 此时options会自动推断为 { max: number } console.log(options.max); // 类型提示正常 return s.split('').slice(0, options.max); } ); // 调用示例 split('hello world'); // 使用默认max:0 split('hello world', { max: 5 }); // 自定义max
内容的提问来源于stack exchange,提问作者Fayeure
相关产品推荐
相关产品推荐

