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

TypeScript:如何让calculation匹配generator的泛型参数类型?

问题:如何让calculation类型匹配generator的参数类型?

存在一个需传入另一函数并在其中调用的工厂函数,该函数的参数要么基于泛型类型,要么无需传入。请说明如何正确定义「calculation」,使其类型与「generator」的参数类型匹配?

原代码示例:

type Model = {id: number};
type Calc = Record<string, number>;
declare function calc(record: Model): Calc;

type OptFnArg<Param, Result> = Param extends void ? () => Result : (arg: Param) => Result;

const run = function <Param>(modelFactory: OptFnArg<Param, Model>) {
    const calculation = (param: Param) => calc(modelFactory(param));
    //^ 如何让`calculation`能被`generator`接受?
    //  类型'(param: Param) => Calc'无法赋值给类型'OptFnArg<Param, Calc>'。

    const result = generator<Param>(calculation);

    return result;
}


declare function generator<Param>(calculation: OptFnArg<Param, Calc>): '🎲'

// 合法调用示例:

run<void>(() => ({id: 1}));
// @ts-expect-error
run<void>((q) => ({id: 1}));

run<number>((id: number) => ({id}));
// @ts-expect-error
run<string>((id: number) => ({id}));

问题根源

当Param为void时,OptFnArg<Param, Calc>对应的是无参函数() => Calc,但你定义的calculation是接受void类型参数的函数(param: void) => Calc——这两个类型在TypeScript中不兼容:无参函数不允许传入任何参数,而接受void参数的函数可以传入undefined或空值,因此类型校验失败。

解决方案

通过泛型条件分支构造完全符合OptFnArg<Param, Calc>类型的calculation函数:

const run = function <Param>(modelFactory: OptFnArg<Param, Model>) {
  // 根据Param的类型构造匹配的calculation函数
  const calculation = (Param extends void 
    ? () => calc(modelFactory()) 
    : (param: Param) => calc(modelFactory(param))
  ) as OptFnArg<Param, Calc>;

  const result = generator<Param>(calculation);

  return result;
}

原理说明

  • 当Param为void时,创建无参函数() => calc(modelFactory()),完全匹配OptFnArg<void, Calc>的要求;
  • 当Param为其他类型时,创建对应参数类型的函数(param: Param) => calc(modelFactory(param)),匹配OptFnArg<Param, Calc>的定义;
  • 类型断言as OptFnArg<Param, Calc>帮助TypeScript正确推断泛型分支后的函数类型,避免编译器报错。

修改后,calculation可完美适配generator的参数类型,同时保留原有的合法调用校验逻辑。


内容的提问来源于stack exchange,提问作者c01nd01r

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 18:20:31