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

TypeScript组合函数中条件返回类型失效问题及解决方法

TypeScript compose函数中条件返回类型失效的原因及解决办法

问题原因

你的compose函数存在两个核心问题导致条件返回类型失效:

  1. 重载定义无法追踪泛型关联性:b是一个依赖泛型B来决定返回类型的高阶函数,但原compose的重载仅将参数函数视为普通的(input: X) => Y类型,无法识别Y与输入参数中B的条件关联,类型推导链在这里断裂。
  2. 实现层的any抹除类型信息:compose的实现里用any处理输入和返回值,直接让TypeScript放弃了所有类型推导,自然无法识别b函数的条件返回类型。

解决办法

需要重新定义compose的类型系统,用递归泛型追踪每个函数的输入输出关联,同时避免any破坏类型推导。以下是修复后的代码:

// 递归推导组合函数的完整类型链
type Compose<T extends Array<(...args: any[]) => any>> = 
  T extends [(x: infer X) => infer Y, ...infer Rest]
    ? Rest extends Array<(...args: any[]) => any>
      ? (x: X) => Compose<Rest> extends (y: Y) => infer Z ? Z : never
      : (x: X) => Y
    : never;

export function compose<T extends Array<(...args: any[]) => any>>(
  ...fns: T
): Compose<T> {
  return (input: any) => fns.reduce((acc, fn) => fn(acc), input) as Compose<T>;
}

/////////////////////////

const a = <I, O>(fn: (args: I) => O) => (args: I & {a: number}): O & {a: number} => {
  return {...fn(args as I), a: 1};
};

const b = <I, O>(fn: (args: I) => O) => <B extends boolean>(args: I & {b: B}): B extends true ? O & {b: number} : O => {
  if (!args.b) {
    return fn(args);
  }
  return {...fn(args), b: 1} as B extends true ? O & {b: number} : O;
};

const fn = (arg: {x: number}) => arg;

// 现在可正确推断b属性存在,类型为number
compose(b, a)(fn)({x: 1, a: 1, b: true}).b; 

关键修改说明

  • 递归泛型Compose:通过递归逐步推导每个函数的输入输出类型,确保前一个函数的输出能正确匹配后一个函数的输入,同时保留高阶函数的泛型参数关联性,让b的条件类型能被正确识别。
  • 移除不安全的any断言:将实现中的as any替换为as Compose<T>,让TypeScript基于定义好的类型链完成推导,而非直接抹除类型信息。
  • 优化b函数的返回断言:替换原有的as any为精准的条件类型断言,进一步强化类型推导的准确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 18:15:39