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

能否从泛型类型元组提取泛型参数为元组?TS函数合并优化

实现fnZip函数的类型优化方案

需求说明

我想要实现一个函数fnZip,它接收一组泛型函数并将其“合并”为一个函数,该函数会接收所有输入函数的参数,并在一次调用中返回所有输入函数的输出。

现有类型安全实现

目前我通过infer推断每个泛型函数的参数和返回类型,实现了类型安全,代码如下:

type Fn<T = any, TReturn = any> = (arg: T) => TReturn;

type FnArg<T extends Fn> = T extends Fn<infer TArg> ? TArg : unknown;
type FnArgTuple<T extends Fn[]> = { [key in keyof T]: FnArg<T[key]> };

type FnReturn<T extends Fn> = T extends Fn<any, infer TReturn> ? TReturn : unknown;
type FnReturnTuple<T extends Fn[]> = { [key in keyof T]: FnReturn<T[key]> };

const fnZip = <T extends ((arg: any) => any)[]>(
  fns: [...T],
): Fn<FnArgTuple<T>, FnReturnTuple<T>> => (
  args,
) => fns.map((fn, idx) => fn(args[idx])) as FnReturnTuple<T>;

优化设想

但我想知道是否有更优雅、更符合惯例的方式,从给定的函数数组中提取函数的参数和返回类型作为元组。以下是我设想的(无法运行的)示例:

type Fn<T = any, TReturn = any> = (arg: T) => TReturn;

const fnZip = <T extends any[], TReturn extends any[]>(
  fns: { [key: number]: Fn<T[key], TReturn[key]> },
): Fn<T, TReturn> => (args) => fns.map((fn, idx) => fn(args[idx])) as TReturn;

核心逻辑补充

我实际想要实现的逻辑是:

[Type<A1, B1>, Type<A2, B2>, ...etc] => Type<[A1, A2, ..etc], [B1, B2, ...etc]>

@jcalz提出的方案(存在推断问题)

@jcalz提出了一个方案,若TypeScript能正确推断第二个泛型类型,该方案本应完美运行,但出于未知原因无法实现:

type Fn<T = any, TReturn = any> = (arg: T) => TReturn;

const fnZip = <T extends any[], TReturn extends { [key in keyof T]: any }>(
  fns: [...{ [key in keyof T]: Fn<T[key], TReturn[key]> }],
): Fn<T, TReturn> => (args) => fns.map((fn, idx) => fn(args[idx])) as TReturn;

const zipped = fnZip([
//     ^? const zipped: Fn<[string, number], [any, any]>
  (x: string) => x.length,
  (y: number) => y.toFixed(),
]);

内容的提问来源于stack exchange,提问作者Jørgen Tau

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 00:47:36