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

如何让TypeScript泛型转换函数根据输入类型推导返回类型?

解决TypeScript泛型转换函数的类型匹配问题

问题核心

你尝试用条件类型实现泛型转换函数,但返回类型始终是联合类型,无法精准匹配输入对应的输出类型。问题根源在于两点:

  1. 函数参数类型写死为Bases,而非绑定到泛型参数B,导致TypeScript无法捕获输入的具体子类型;
  2. 未具体化的泛型条件类型会保留表达式形式,传入联合类型时直接展开为联合结果。

正确实现方案

方案1:函数重载(最直观易维护)

通过重载签名明确输入与输出的类型映射,TypeScript会自动根据输入匹配对应重载:

// 重载签名:定义输入输出的精准映射
function transformGeneric(base: BaseA): TransformedA;
function transformGeneric(base: BaseB): TransformedB;
// 兜底实现签名
function transformGeneric(base: Bases): Transformed | null;

// 函数实现
function transformGeneric(base: Bases): Transformed | null {
  switch (base.type) {
    case "A":
      return transformA(base);
    case "B":
      return transformB(base);
    default:
      return null;
  }
}

// 类型推断正常
const transformedA = transformGeneric(baseASample); // 类型为TransformedA
const transformedB = transformGeneric(baseBSample); // 类型为TransformedB

方案2:泛型+类型映射表(适合扩展更多类型)

用映射表明确输入类型到输出类型的对应关系,同时将参数类型绑定到泛型参数,让TypeScript精准推断:

// 定义输入类型到输出类型的映射表
type TransformMap = {
  A: TransformedA;
  B: TransformedB;
};

// 修正后的泛型转换函数
const transformGeneric = <B extends Bases>(base: B): B extends { type: infer T } ? TransformMap[T] : null => {
  switch (base.type) {
    case "A":
      return transformA(base as BaseA) as any;
    case "B":
      return transformB(base as BaseB) as any;
    default:
      return null as any;
  }
};

// 类型推断正常
const transformedA = transformGeneric(baseASample); // 类型为TransformedA
const transformedB = transformGeneric(baseBSample); // 类型为TransformedB

这里的类型断言是因为TypeScript在switch分支中无法自动将base缩小到对应子类型,属于必要的辅助手段。

原代码问题解析

  • transformGeneric:返回类型直接写Transformed | null,丢失了具体子类型的精准信息;
  • transformGeneric2:参数类型为Bases,泛型B未与参数绑定,条件类型无法根据输入收缩,最终返回联合类型;
  • transformGeneric3:同样未将参数类型绑定到泛型,且条件分支仅处理了BaseA的情况,BaseB的返回类型仍为宽泛的Transformed。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 17:16:04