如何模拟基于字符串的枚举

时间:2016-10-28 18:23:44

标签: typescript enums string-literals typechecking

我的API来自API,可以是"orange""apple""banana"

首先我创建了一个类型:

type Fruit = "orange" | "apple" | "banana";

然后,我可以将API中的值键入为Fruit;

type Fruit = "orange" | "apple" | "banana";

function getFruitFromApi(): Fruit {
    // simulating random result
    const fruits: Fruit[] = ["orange", "apple", "banana"];

    return fruits[Math.floor(Math.random() * 3)];
}

const fruit: Fruit = getFruitFromApi();

switch (fruit) {
    case "orange": break;
    case "apple": break;
    case "banana": break;
}

没关系,但我想避免在交换机中手动输入这些字符串。我想要Fruit.OrangeFruit.AppleFruit.Banana之类的内容。所以基本上就像枚举,但值与字符串而不是数字匹配。

2 个答案:

答案 0 :(得分:3)

从这个老问题中得出答案: https://stackoverflow.com/a/35257367/105937

使用TS 1.8或更高版本,我们可以执行以下操作:

type Fruit = "orange" | "apple" | "banana";

const Fruit = {
    Orange: "orange" as Fruit,
    Apple:  "apple" as Fruit,
    Banana: "banana"  as Fruit
};

然后将其用作Fruit.Orange,将其解析为"orange"

答案 1 :(得分:0)

您可以指定枚举的值,但如果它们不是数字,则编译器不会喜欢它。
您可以强制转换为any以删除编译错误:

enum Fruit {
    Orange = "orange" as any,
    Apple = "apple" as any,
    Banana = "banana" as any
}

function getFruitFromApi(): Fruit {
    const fruits = ["orange", "apple", "banana"];

    return fruits[Math.floor(Math.random() * 3)] as any;
}

另一种选择是使用常规枚举并将接收到的字符串转换为该枚举:

enum Fruit {
    Orange,
    Apple,
    Banana
}

function getFruitFromApi(): Fruit {
    const fruits = ["orange", "apple", "banana"];
    const fruit = fruits[Math.floor(Math.random() * 3)];

    for (var key in Fruit) {
        if (typeof key === "string" && key.toLowerCase() === fruit) {
            return (Fruit as any)[key];
        }
    }

    return null;
}

const fruit: Fruit = getFruitFromApi();

switch (fruit) {
    case Fruit.Orange:
        console.log("orange");
        break;
    case Fruit.Apple:
        console.log("apple");
        break;
    case Fruit.Banana:
        console.log("banana");
        break;
}