Context假设我有以下带有字符串值的枚举:
enum Fruit {
Apple = "apple",
Orange = "orange",
Banana = "banana",
Pear = "pear"
}
用户总是从下拉列表中输入文字string
值("apple"
、"banana"
、"orange"
、"pear"
(,以消除无效输入的可能性-我需要将其转换回类型Fruit
,即类似于以下的内容:
function getFruit(fruit: string): Fruit {
switch (fruit) {
case "apple":
return Fruit.Apple
case "banana":
return Fruit.Banana
case "orange":
return Fruit.Orange
case "pear":
return Fruit.Pear
default:
// I DON'T WANT THIS!
return Fruit.Pear
}
}
问题
- switch语句需要维护开销
getFruit()
函数:- 接受任何未表示为可接受字符串值的并集的
string
(如果使用除"apple"
、"banana"
、"orange"
、"pear"
之外的任何内容,typescript都不会引发编译错误。(我知道我可以使用绝对字符串的并集作为type
,但这会带来更大的开销 - 需要提供CCD_ 14的情况并返回默认结果
- 接受任何未表示为可接受字符串值的并集的
问题
有没有一种更优雅的方法可以做到这一点?可能使用type
/typeof
/keyof
或任何其他操作?
理想情况下,我希望能够:
- 完全消除switch语句-(因此没有维护开销(
getFruit()
函数仅以编程方式获取枚举中包含的string
值(无需手动声明和维护绝对字符串的并集(
p.s.我不在乎是否需要使用替代类型而不是enum
——这是重要的功能!
最佳尝试到目前为止,我最接近的解决方案是:
type Fruits = "apple" | "banana" | "orange" | "pear"
let Fruit = {
Apple = "apple",
Orange = "orange",
Banana = "banana",
Pear = "pear"
}
type Fruit = keyof typeof Fruit
function parseFruit(fruit: Fruits): Fruit {
return Object.keys(Fruit).find((key) => {
return Fruit[key as Fruit] === fruit
}) as Fruit
}
这仍然需要对字符串文字并集CCD_ 21和CCD_。如果我能想出如何以编程方式创建字符串文字联合type Fruits
,那么这个解决方案将是"完美的"。
您可以迭代枚举值并找到Fruit
function getFruit(fruit: string): Fruit | null {
return Object.values(Fruit).find(item => item === fruit) ?? null
}