You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让传入函数的被装饰回调函数的参数类型正确推断?

如何让传入函数的被装饰回调函数的参数类型正确推断?

这个问题我之前踩过坑!本质就是TypeScript的类型推断顺序和NoInfer的使用逻辑导致的,咱们拆解清楚然后解决它:

你猜的完全没错——TypeScript的类型推断是按参数从左到右依次进行的。当你调用fn(decorator(v => {}), { asNumber: true })时,TS会先处理第一个参数decorator(v => {}),这时候第二个参数还没被读取,所以泛型T会先用上默认值false;等它读到第二个参数{ asNumber: true }时,虽然会把T修正为true,但TS不会“回头”再更新第一个参数里回调的类型了——毕竟类型推断是单向的,不是双向绑定的。

而直接传回调时没问题,是因为回调本身的参数类型会反向约束T,但被decorator包裹后,回调的类型被一层函数包装了,TS没法直接从包装后的函数里提取出原始回调的参数类型来反向推断T。

方案一:调整参数顺序(最简单直接)

把options放在第一个参数,callback放在第二个。这样TS会先从options推断出T,再把T应用到callback上,完全避开推断顺序的问题:

type Callback<T extends boolean> = (v: T extends true ? number : string) => void;
declare function fn<T extends boolean = false>(
  options?: { asNumber?: T },
  callback: Callback<NoInfer<T>>
): NoInfer<T>;

调用的时候就变成fn({ asNumber: true }, decorator(v => {})),这时候v会被正确推断为number,完美解决。

方案二:用重载明确类型分支(不修改参数顺序)

如果你不想调整参数顺序,可以给fn写函数重载,把asNumber为true和false的情况分开定义,让TS直接匹配对应的分支:

type Callback<T extends boolean> = (v: T extends true ? number : string) => void;
declare function decorator<F extends Function>(fn: F): F;

// 重载1:明确传asNumber: true的情况
declare function fn(callback: Callback<true>, options: { asNumber: true }): true;
// 重载2:不传asNumber或传false的情况
declare function fn(callback: Callback<false>, options?: { asNumber?: false }): false;

这样调用fn(decorator(v => {}), { asNumber: true })时,TS会直接匹配第一个重载,v的类型自动变成number,完全不会有推断问题。

方案三:重构回调的泛型定义(更灵活)

我们可以把回调的泛型从boolean改为直接对应参数类型(string或number),让T从回调参数和options双向推断,这样不管参数顺序如何,TS都能正确匹配:

// 直接用参数类型作为泛型,不用boolean中转
type Callback<T> = (v: T) => void;
// 根据参数类型推导asNumber的布尔值
type AsNumberFlag<T> = T extends number ? true : false;

declare function decorator<F extends Function>(fn: F): F;

declare function fn<T extends string | number = string>(
  callback: Callback<T>,
  options?: { asNumber?: AsNumberFlag<T> }
): AsNumberFlag<T>;

这个方案的好处是泛型更直观,TS可以从回调参数或者options任意一方推断类型,双向约束,调用时不管是直接传回调还是传装饰后的回调都能正常工作。

如果只是临时解决问题,方案一最快;如果不能改参数顺序,方案二的重载最稳妥;如果想让类型系统更灵活,方案三的重构更合适。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 12:03:04