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

如何在TypeScript的switch语句中正确为多个类实现类型守卫?

在TypeScript中用Switch语句实现类的联合类型守卫

方案一:使用可辨识联合(推荐)

给每个类添加一个唯一的字面量类型属性,让TypeScript能自动识别所有可能的类型分支,无需default分支也不会报错:

class A {
  readonly type: 'A' = 'A';
}
class B {
  readonly type: 'B' = 'B';
}
class C {
  readonly type: 'C' = 'C';
}

type OneOfThem = A | B | C;

function test(foo: OneOfThem): string {
    switch(foo.type) {
        case 'A':
            return "A";
        case 'B':
            return "B";
        case 'C':
            return "C";
        // TypeScript会自动检测所有分支已覆盖,无需default
    }
}

这种方式利用了TypeScript的可辨识联合类型特性,每个类的type属性是唯一的字面量,TS能精准推断所有可能的情况,因此不会抛出缺少return语句的错误。

方案二:结合instanceof与never断言

如果不想给类添加额外属性,可以用instanceof做类型判断,但需要配合never类型断言让TS确认所有分支已覆盖:

class A {}
class B {}
class C {}

type OneOfThem = A | B | C;

function test(foo: OneOfThem): string {
    switch(true) {
        case foo instanceof A:
            return "A";
        case foo instanceof B:
            return "B";
        case foo instanceof C:
            return "C";
        default:
            // 用never断言告诉TS此处不会执行到,若新增类型会触发编译错误
            const _unreachable: never = foo;
            throw new Error(`未知类型: ${_unreachable}`);
    }
}

为什么你之前的方案无效?

  • 直接用foo.constructor作为switch表达式:TS无法推断foo.constructor的类型是确切的构造函数,联合类型下的constructor是多个构造函数的联合,TS无法确认每个case都覆盖了所有可能,因此仍会认为存在未处理的分支。
  • 直接在case中写instanceof:switch的case要求是常量表达式,foo instanceof A是布尔表达式,不能直接作为case值,所以这种写法本身语法就不合法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 21:30:19