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

如何在TypeScript中使用switch case细化继承基础接口的接口?

在TypeScript中用switch case窄化继承自基础接口的类型

你的代码里没法正确窄化类型的原因,是用了泛型<T extends X>——TypeScript会把x当成所有X子类型的交集,而非你期望的A | B联合类型,自然没法在switch分支里识别具体子接口的专属属性。

要解决这个问题,只需要把函数参数类型改成A | B(或直接用X的联合子类型),去掉泛型声明即可:

interface X {
  type: string;
}

interface A extends X {
  type: 'a';
  a: number;
}

interface B extends X {
  type: 'b';
  b: string;
}

// 参数类型改为A | B,无需泛型
function processX(x: A | B) {
  switch (x.type) {
    case 'a':
      // TypeScript自动将x窄化为A类型,可安全访问a属性
      console.log(x.a.toFixed(2));
      break;
    case 'b':
      // 自动窄化为B类型,访问b属性无报错
      console.log(x.b.toUpperCase());
      break;
    default:
      // 新增default分支做穷尽检查,避免遗漏未知类型
      const _exhaustiveCheck: never = x;
      throw new Error(`Unknown type: ${x.type}`);
  }
}

核心原理

这里用到了TypeScript的判别式联合类型(Discriminated Unions):

  • 所有子接口都继承了基础接口X的type属性,且给type赋值了具体的字面量类型('a'、'b')
  • 当用switch判断x.type时,TypeScript会根据字面量值自动把变量类型窄化到对应子接口,此时就能安全访问该子接口的独有属性。

如果必须保留泛型(比如需要返回和输入同类型的值),可以给泛型加上A | B的约束,这样也能实现类型窄化:

function processX<T extends A | B>(x: T): T {
  switch (x.type) {
    case 'a':
      x.a; // 正确识别为A类型
      break;
    case 'b':
      x.b; // 正确识别为B类型
      break;
  }
  return x;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 12:22:38