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

TypeScript中compose函数类型定义报错及参数类型未知问题求助

解决TypeScript compose函数的类型定义问题

问题分析

原代码存在两个核心问题:

  1. 索引类型错误:keyof Arr会包含数组的非数字键(如"length"),无法直接用于索引[any,...Arr]类型;同时原泛型设计将返回值元组与函数参数分离,导致类型关联断裂。
  2. 参数类型推断失败:独立的Begin泛型参数无法与函数链的输入类型建立关联,导致返回函数的参数类型被推断为unknown。

解决方案

重新设计泛型约束,让函数链的输入输出类型形成强关联:

方案一:映射类型约束函数链

// 获取元组首个元素类型
type First<T extends any[]> = T extends [infer U, ...any[]] ? U : never;
// 获取元组末位元素类型
type Last<T extends any[]> = T extends [...any[], infer U] ? U : never;
// 获取函数的参数类型
type ArgType<F> = F extends (arg: infer A) => any ? A : never;
// 获取函数的返回值类型
type ReturnType<F> = F extends (...args: any[]) => infer R ? R : never;

// 约束函数元组:每个函数的参数是前一个函数的返回值
type ComposeFns<T extends any[]> = {
  [I in keyof T]: I extends `${number}` 
    ? I extends "0"
      ? (arg: any) => any
      : (arg: ReturnType<T[Number(I)-1]>) => ReturnType<T[Number(I)]>
    : never;
} & { length: T['length'] };

function compose<T extends ((arg: any) => any)[]>(
  ...fns: T extends ComposeFns<T> ? T : never
): (arg: ArgType<First<T>>) => ReturnType<Last<T>> {
  return function(val) {
    return fns.reduce((input, fn) => fn(input), val) as ReturnType<Last<T>>;
  };
}

方案二:递归类型计算返回结果

// 递归计算compose的返回函数类型
type ComposeResult<T extends any[]> = 
  T extends [(arg: infer A) => infer R]
    ? (arg: A) => R
    : T extends [(arg: infer A) => infer R, ...infer Rest]
      ? ComposeResult<[(x: R) => R, ...Rest]> extends (arg: infer _) => infer FinalR
        ? (arg: A) => FinalR
        : never
      : never;

function compose<T extends ((arg: any) => any)[]>(...fns: T): ComposeResult<T> {
  return function(val) {
    return fns.reduce((input, fn) => fn(input), val) as ComposeResult<T>;
  };
}

测试验证

使用你提供的测试代码:

function a(p: string): boolean {
  return true;
}

function b(p: boolean): number {
  return 1;
}

function c(p: number): Array<string> {
  return [];
}

const abc = compose(a, b, c);
// 此时abc的类型被正确推断为:(arg: string) => string[]

两种方案都能解决原有的类型错误,并且正确推断返回函数的参数和返回值类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:39:56