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

TypeScript实现compose时如何正确推导各传入函数的参数类型

TypeScript 实现compose函数的精确类型推导方案

问题描述

实现闭包函数compose组合工具时遇到类型推导失效问题:

  • 待组合的闭包函数统一遵循(config: 任意配置) => (a: number) => number契约,例如:
    const func1 = (arg1: {a: number}) => (a: number) => number
    const func2 = (arg1: {b: string}) => (a: number) => number
    
  • compose调用形式为const composed = compose({func1, func2}),返回的组合函数接收两个参数:
    • 第一个参数:传入执行链最内层的数值
    • 第二个参数:可选配置对象,key与传入compose的函数名一一对应,value为对应函数所需的入参配置
  • 执行逻辑等价于从右到左串行执行所有闭包返回的内层函数,例如composed(33, {func1: {a:1}})等价于func1({a:1})(func2(undefined)(33))
  • 现有实现中config参数的所有属性都被推导为any,无法获得对应函数的入参类型提示

问题原因

原有泛型定义存在两个缺陷:

  1. 泛型参数T仅约束了funcs对象的key类型,没有绑定整个funcs对象的结构,无法保留每个key对应的精确函数类型
  2. 映射config类型时,使用typeof funcs[T]索引类型,其中T是所有key的联合类型,最终拿到的是所有函数类型的联合,再加上基础类型MyFunction把入参写死为any,最终推导结果全部为any

修复代码

调整泛型定义,直接绑定传入funcs对象的完整类型,再通过映射类型逐个提取每个函数的入参类型:

type ComposableFunction = (config: any) => (a: number) => number;

export const compose = <T extends Record<keyof T, ComposableFunction>>(funcs: T) => {
  // 内部组合实现逻辑可自行补充,以下为参考实现
  const funcKeys = Object.keys(funcs) as (keyof T)[];

  return (
    value: number,
    config?: Partial<{
      [K in keyof T]: Parameters<T[K]>[0]
    }>,
  ) => {
    let execResult = value;
    // 按从右到左顺序执行,匹配f1(f2(value))的逻辑
    for (let i = funcKeys.length - 1; i >= 0; i--) {
      const currentKey = funcKeys[i];
      const currentInnerFn = funcs[currentKey](config?.[currentKey]);
      execResult = currentInnerFn(execResult);
    }
    return execResult;
  };
};

推导效果验证

const func1 = (arg1: {a: number}) => (a: number) => a + arg1.a;
const func2 = (arg1: {b: string}) => (a: number) => a + Number(arg1.b);

const composedFn = compose({func1, func2});
// 编写第二个配置参数时,TS会自动提示:
// func1 对应配置类型为 {a: number}
// func2 对应配置类型为 {b: string}
const result = composedFn(33, {func1: {a: 1}}); // 类型校验正常,无any问题

核心要点

  • 泛型参数需要直接捕获传入的整个funcs对象类型,而非仅捕获key的联合类型,才能保留每个属性的精确函数签名
  • 映射配置类型时,需要针对遍历过程中的单个keyK,通过T[K]获取对应位置的函数类型,再通过Parameters提取其第一个入参类型,不能用全量key联合类型做索引

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 18:03:18