网站搜索

类型 - 带参数的 Typescript 枚举


我想要严格类型的可变对象,就像 Haxe 的枚举一样。

在 Haxe 中,你可以做

enum Color {
  Red;
  Rgb(r:Int, g:Int, b:Int);
  Rgba(r:Int, g:Int, b:Int, a:Int);
}

我希望只有当我的对象是 Rgba 时,才能访问 a 参数,而如果我的对象是 Red,则无法访问任何参数。

我并不在意在 TypeScript 中是否使用 enum 关键字。

在 Typescript 中有办法实现吗?

答案#1

从版本 2.0 开始,TypeScript 在某种程度上支持标记联合。一般语法是

type MyType = A | B | C …;

其中 A、B 和 C 是接口。MyType 对象可以是这些类型中的任何一个,而不能是其他类型。公告给了一个快速示例:

interface Square {
    kind: "square";
    size: number;
}

interface Rectangle {
    kind: "rectangle";
    width: number;
    height: number;
}

interface Circle {
    kind: "circle";
    radius: number;
}

type Shape = Square | Rectangle | Circle;

function area(s: Shape) {
    // In the following switch statement, the type of s is narrowed in each case clause
    // according to the value of the discriminant property, thus allowing the other properties
    // of that variant to be accessed without a type assertion.
    switch (s.kind) {
        case "square": return s.size * s.size;
        case "rectangle": return s.width * s.height;
        case "circle": return Math.PI * s.radius * s.radius;
    }
}

然而,这些联合类型的类型安全需要手动通过所谓的“判别属性类型保护”来保护和检查,如示例所示(检查 s.kind)。