我已经很多年没有使用Typescript了,不记得也不知道如何正确地在Switch声明中输入保护许多类.

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

type OneOfThem = A | B | C;

function test(foo: OneOfThem): string {
    switch(/* something using foo */) {
        /* A */:
            return "A";
        /* B */:
            return "B";
        /* C */:
            return "C";

        /* should not need to use "default" as all cases are handled */
    }
}

我发现并try 了几个选项,例如:

但它们都不起作用(Function lacks ending return statement and return type does not include 'undefined').

我的记忆是否起了作用,而这在课堂上是不可能的?

推荐答案

将额外成员添加到要在Switch陈述中使用的三个类中

对于您的情况,这确实可能是最简单的解决方案:它使用Discriminated Union,通过向每个类添加discriminant个成员,具有literal种类型(即不仅仅是stringnumber),以便您(和TypScript)可以区分foo来自哪个类:

class A {
    readonly kind = "a"
    //       ^? "a" string literal, not just `string`
}
class B {
    kind: "b" = "b"
    // ^? "b" string literal, as explicitly typed
}
class C {
    kind = "c" as const
    // ^? "c" string literal, thanks to the const assertion
}

然后简单地根据这kind个区分属性进行区分:

function test(foo: OneOfThem): string { // Okay
    switch (foo.kind) {
        case "a":
            foo
            //^? A inferred by TS, based on `foo.kind === "a"` type guard
            return "A";
        case "b":
            foo
            //^? B
            return "B";
        case "c":
            foo
            //^? C
            return "C";
        /* should not need to use "default" as all cases are handled */
    }
}

Playground Link

Typescript相关问答推荐

如何使用TypScript限制允许对JavaScript值进行的操作集?

返回对象的TypScript构造函数隐式地替换This的值来替换super(.)的任何调用者?

数组文字中对象的从键开始枚举

无法绑定ngModel.条件ngSwitchCase中的错误

如何使用Zod使一个基于其他字段值的字段为必填字段?

PrimeNG日历需要找到覆盖默认Enter键行为的方法

匿名静态类推断组成不正确推断

从TypeScrip中的其他类型检索泛型类型

如何在深度嵌套的Reaction路由对象中隐藏父级?

如何将定义模型(在Vue 3.4中)用于输入以外的其他用途

从泛型类型引用推断的文本类型

如何正确调用创建的类型?

类型脚本中参数为`T`和`t|unfined`的重载函数

如何避免多个类型参数重复?

递归类型别名的Typescript 使用

TS不能自己推断函数返回类型

如何键入';v型';

如何在Vuetify 3中导入TypeScript类型?

Angular另一个组件的nativeelement未定义

React-Router V6 中的递归好友路由