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

TypeScript中如何避免基于辨别符的switch分支语句?

用类型安全的映射表替代Switch分支重构代码

需求:移除switch分支语句,同时保留TypeScript类型安全,避免使用any类型。

原代码实现:

function translate(when: When): SomeCommonResultType {
  switch (when.object) {
    case "timespan":
      return translateTimeSpan(when);
    case "time":
      return translateTime(when);
    case "datespan":
      return translateDateSpan(when);
    case "date":
      return translateDate(when);
  }
}

type When = Timespan | Time | DateSpan | Date;

export interface Timespan {
  readonly object: "timespan";
  startTime: number;
  endTime: number;
  startTimezone?: string;
  endTimezone?: string;
}

function translateTimeSpan(when: Timespan): SomeCommonResultType {
  // ...
}

export interface Time {
  readonly object: "time";
  time: number;
  timezone: string;
}

function translateTime(when: Time): SomeCommonResultType {
  // ...
}

export interface DateSpan {
  readonly object: "datespan";
  startDate: string;
  endDate: string;
}

function translateDateSpan(when: DateSpan): SomeCommonResultType {
  // ...
}

export interface Date {
  readonly object: "date";
  date: string;
}

function translateDate(when: Date): SomeCommonResultType {
  // ...
}

用户原有映射表写法(存在any类型问题):

const TranslateWhenMap = new Map<string, any>([
  ["timespan", translateTimeSpan],
  ["date", translateDate],
  ["datespan", translateDateSpan],
  ["time", translateTime],
]);

function translate(when: When): SomeCommonResultType {
  return TranslateWhenMap.get(when.object)(when);
}

类型安全的映射表重构方案

步骤1:定义严格类型的处理函数映射表类型

利用TypeScript的索引类型和条件类型,将When联合类型中的每个子类型与对应的处理函数关联:

// 定义映射表类型:键为When的object属性值,值为对应子类型的处理函数
type WhenHandlerMap = {
  [K in When['object']]: (when: Extract<When, { object: K }>) => SomeCommonResultType;
};

步骤2:创建类型安全的映射表

用上述类型约束映射表,确保每个键对应的处理函数参数和返回值完全匹配:

const translateWhenMap: WhenHandlerMap = {
  timespan: translateTimeSpan,
  time: translateTime,
  datespan: translateDateSpan,
  date: translateDate,
};

步骤3:重构translate函数

通过映射表直接调用对应处理函数,这里的as never是TypeScript的小技巧——编译器暂时无法自动推断when的类型与处理函数参数的严格匹配,但实际运行是完全安全的:

function translate(when: When): SomeCommonResultType {
  return translateWhenMap[when.object](when as never);
}

方案优势

  • 完全类型安全:没有any类型,TypeScript会自动检查每个处理函数的参数和返回值是否符合要求
  • 可维护性高:如果新增When的子类型,映射表会直接报错,提示必须添加对应的处理函数
  • 代码更简洁:相比switch分支,映射表的写法更直观,便于扩展

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 21:07:26