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

TypeScript中根据参数数组返回对应泛型类型数组的实现问询

解决方案:基于元组映射的精准类型推断

要实现返回函数数组的每个元素类型与输入参数数组一一对应,且支持每个函数独立的泛型参数,你需要利用TypeScript的可变参数泛型和元组映射类型,替代原代码中全局统一的泛型T和X。

步骤1:重构基础类型定义

先定义带区分标志的参数类型(discriminated union),以及对应的函数类型:

// 基础函数类型:各自独立泛型
type FirstThing<T> = () => T;
type SecondThing<T, X> = (something: X) => T;

// 参数的区分联合类型:通过option1区分两种参数
type BaseParam = { option2?: boolean };
type FirstParam = BaseParam & { option1: "firstThing" };
type SecondParam = BaseParam & { option1: "secondThing" };
type FunctionParam = FirstParam | SecondParam;

步骤2:实现泛型映射类型

定义辅助类型,将输入的参数元组映射为对应的函数元组,每个位置的函数类型由参数的option1决定:

// 将单个参数转换为对应函数类型的辅助类型
type ParamToFunc<P, T, X = never> =
  P extends FirstParam ? FirstThing<T> :
  P extends SecondParam ? SecondThing<T, X> :
  never;

// 将参数元组转换为函数元组的映射类型
type ParamsToFuncs<
  P extends readonly FunctionParam[],
  Ts extends readonly any[],
  Xs extends readonly any[]
> = {
  [K in keyof P]: ParamToFunc<P[K], Ts[K], Xs[K]>;
};

步骤3:实现泛型函数

编写函数,利用可变参数泛型捕获参数元组和对应的类型元组,返回精准映射的函数元组:

function someFunction<
  P extends readonly FunctionParam[],
  Ts extends readonly any[],
  Xs extends readonly any[]
>(params: P): ParamsToFuncs<P, Ts, Xs> {
  return params.map((fp) => {
    if (fp.option1 === "firstThing") {
      // 返回FirstThing类型函数,返回值需符合对应位置的Ts[K]
      return (() => "aa" as unknown as Ts[number]) as any;
    } else {
      // 返回SecondThing类型函数,参数类型符合Xs[K],返回值符合Ts[K]
      return ((smth: Xs[number]) => "bb" as unknown as Ts[number]) as any;
    }
  }) as any;
}

步骤4:调用示例

调用时指定参数元组、返回值类型元组和参数类型元组,TypeScript会精准推断每个返回函数的类型:

// f1: FirstThing<string>,f2: SecondThing<number, boolean>
const [f1, f2] = someFunction<
  [FirstParam, SecondParam],
  [string, number],
  [never, boolean]
>([{ option1: "firstThing" }, { option1: "secondThing" }]);

// 验证类型:f1无参数,返回string
const str = f1(); // str: string
// 验证类型:f2需要boolean参数,返回number
const num = f2(true); // num: number

简化调用(可选)

如果觉得指定三个泛型参数繁琐,可以通过类型断言在参数中携带类型信息,让TypeScript自动推断:

// 扩展参数类型,携带类型标记
type TypedFirstParam<T> = FirstParam & { _returnType?: T };
type TypedSecondParam<T, X> = SecondParam & { _returnType?: T; _argType?: X };

function someFunctionAuto<
  P extends readonly (TypedFirstParam<any> | TypedSecondParam<any, any>)[]
>(params: P): {
  [K in keyof P]: P[K] extends TypedFirstParam<infer T>
    ? FirstThing<T>
    : P[K] extends TypedSecondParam<infer T, infer X>
      ? SecondThing<T, X>
      : never;
} {
  return params.map((fp) => {
    if (fp.option1 === "firstThing") {
      return (() => "aa" as unknown as P[K]["_returnType"]) as any;
    } else {
      return ((smth: P[K]["_argType"]) => "bb" as unknown as P[K]["_returnType"]) as any;
    }
  }) as any;
}

// 调用时无需手动指定泛型,通过类型标记自动推断
const [f3, f4] = someFunctionAuto([
  { option1: "firstThing", _returnType: undefined as string },
  { option1: "secondThing", _returnType: undefined as number, _argType: undefined as boolean }
]);
// f3: FirstThing<string>,f4: SecondThing<number, boolean>

核心原理

  • 用可变参数泛型捕获输入的参数元组和类型元组,避免全局统一泛型的限制。
  • 用元组映射类型将参数元组的每个元素转换为对应的函数类型,实现位置一一对应。
  • 利用discriminated union区分不同参数类型,确保类型推断的准确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 03:57:04