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

如何基于输入对象枚举type属性实现TypeScript条件返回类型?

解决TypeScript根据枚举值确定函数返回类型的问题

问题分析

你的代码存在三个核心问题:

  1. 枚举语法错误:enum CustomType = { 应改为 enum CustomType {
  2. 泛型条件类型的推断限制:TypeScript无法在函数内部的switch分支中精确推断泛型T的具体类型,导致返回值与条件类型不匹配
  3. 缺少默认分支:TypeScript认为switch可能未覆盖所有枚举情况,因此提示缺少返回语句

可行的实现方案

方案一:使用函数重载

函数重载能明确指定每个枚举值对应的参数和返回类型,TypeScript可以准确推断调用时的返回类型:

enum CustomType {
  TypeA = 'TYPEA',
  TypeB = 'TYPEB',
  TypeC = 'TYPEC'
}

class ClassA {}
class ClassB {}
class ClassC {}

// 定义重载签名,明确每个type对应的返回类型
function construct(param: { type: CustomType.TypeA } & Record<string, any>): ClassA;
function construct(param: { type: CustomType.TypeB } & Record<string, any>): ClassB;
function construct(param: { type: CustomType.TypeC } & Record<string, any>): ClassC;

// 实现函数,返回联合类型
function construct(param: { type: CustomType } & Record<string, any>): ClassA | ClassB | ClassC {
  switch(param.type) {
    case CustomType.TypeA:
      return new ClassA();
    case CustomType.TypeB:
      return new ClassB();
    case CustomType.TypeC:
      return new ClassC();
    default:
      // 处理不可能的情况,避免TypeScript报错
      throw new Error(`未知类型: ${param.type}`);
  }
}

// 调用示例,TS会正确推断返回类型为ClassA
const instanceA = construct({ type: CustomType.TypeA });

方案二:使用类型映射+泛型

通过定义枚举到类的映射类型,配合泛型和类型断言实现需求,适合需要扩展枚举值的场景:

enum CustomType {
  TypeA = 'TYPEA',
  TypeB = 'TYPEB',
  TypeC = 'TYPEC'
}

class ClassA {}
class ClassB {}
class ClassC {}

// 定义枚举到类的映射关系
type TypeToClass = {
  [CustomType.TypeA]: ClassA;
  [CustomType.TypeB]: ClassB;
  [CustomType.TypeC]: ClassC;
};

function construct<T extends CustomType>(param: { type: T } & Record<string, any>): TypeToClass[T] {
  switch(param.type) {
    case CustomType.TypeA:
      return new ClassA() as TypeToClass[T];
    case CustomType.TypeB:
      return new ClassB() as TypeToClass[T];
    case CustomType.TypeC:
      return new ClassC() as TypeToClass[T];
    default:
      throw new Error(`未知类型: ${param.type}`);
  }
}

// 调用示例,TS推断返回类型为ClassB
const instanceB = construct({ type: CustomType.TypeB });

说明

两种方案都能实现根据枚举值动态确定返回类型的需求:

  • 函数重载更直观,适合枚举值较少的场景
  • 类型映射方案扩展性更强,新增枚举值时只需修改TypeToClass映射即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 23:25:22