我在TypeScript中定义了以下enum:
enum Color{
Red, Green
}
现在在我的函数中,我以字符串的形式接收颜色。我尝试了以下代码:
var green= "Green";
var color : Color = <Color>green; // Error: can't convert string to enum
如何将该值转换为enum?
我在TypeScript中定义了以下enum:
enum Color{
Red, Green
}
现在在我的函数中,我以字符串的形式接收颜色。我尝试了以下代码:
var green= "Green";
var color : Color = <Color>green; // Error: can't convert string to enum
如何将该值转换为enum?
当前回答
枚举
enum MyEnum {
First,
Second,
Three
}
示例使用
const parsed = Parser.parseEnum('FiRsT', MyEnum);
// parsed = MyEnum.First
const parsedInvalid= Parser.parseEnum('other', MyEnum);
// parsedInvalid = undefined
忽略区分大小写的解析
class Parser {
public static parseEnum<T>(value: string, enumType: T): T[keyof T] | undefined {
if (!value) {
return undefined;
}
for (const property in enumType) {
const enumMember = enumType[property];
if (typeof enumMember === 'string') {
if (enumMember.toUpperCase() === value.toUpperCase()) {
const key = enumMember as string as keyof typeof enumType;
return enumType[key];
}
}
}
return undefined;
}
}
其他回答
提供的大多数答案都没有对Enums提供广泛的支持。允许OP请求只从字符串值中获取Enum,但是Enum也允许其他值。
interface StandardEnum<T> {
[id: string]: T | string;
[nu: number]: string;
}
/**
* Converts the given representation of the value of one enumerated constant to an equivalent enumerated type.
*
* @param type - An enumeration type
* @param value - A value to convert
*/
export const genericValueToEnum = <T, K extends StandardEnum<T>> (
type: StandardEnum<T>,
value: K[keyof K]
): T | undefined => {
const keys = Object.keys(type); // ...but, not really.
const values = Object.values(type)
// Filter enum member names because `Object.values()` includes them.
.filter((value) => !(
typeof value === 'string' &&
keys.includes(value) &&
type[value] !== value
));
return values.includes(value)
? value as unknown as T
: undefined;
}
这将适用于所有枚举,无论它们多么复杂(或奇怪),只要它们没有被标记。
enum OddEnum {
None = -1,
No = 0,
Yes = 1,
Twenty = '20'
Other = 'Other',
MORE = 'More',
};
genericValueToEnum(OddEnum, -1); // => -1 as OddEnum;
genericValueToEnum(OddEnum, 'Other'); // => 'Other' as OddEnum;
genericValueToEnum(OddEnum, 'MORE'); // => undefined;
我还遇到了同样的编译器错误。只是Sly_cardinal方法的一个稍短的变种。
var color: Color = Color[<string>colorId];
其他的变化可以是
const green= "Green";
const color : Color = Color[green] as Color;
打印稿1.倍
如果你确定输入字符串与Color enum完全匹配,那么使用:
const color: Color = (<any>Color)["Red"];
在输入字符串可能不匹配Enum的情况下,使用:
const mayBeColor: Color | undefined = (<any>Color)["WrongInput"];
if (mayBeColor !== undefined){
// TypeScript will understand that mayBeColor is of type Color here
}
操场上
如果我们没有将enum转换为<任意>类型,那么TypeScript将显示错误:
元素隐式具有“any”类型,因为索引表达式不是类型“number”。
这意味着默认情况下,TypeScript Enum类型与数字索引一起工作。 let c = Color[0],但是没有像let c = Color["string"]这样的字符串索引。这是微软团队针对更一般问题对象字符串索引的一个已知限制。
2.打印稿x-4x
TypeScript移动到typeof概念的键。
如果some使用字符串值enum:
enum Color {
Green = "GRN",
Red = "RD"
}
然后有语言解决方案映射键值(颜色。Green -> "GRN")只是通过访问枚举成员,但没有简单的方法来做相反的事情("GRN" -> Color.Green)。通过使用反向映射:
请记住,字符串enum成员不会得到反向映射 根本就不存在。
一种可能的解决方案是手动检查值并将值强制转换为enum。请注意,它只适用于字符串枚举。
function enumFromStringValue<T> (enm: { [s: string]: T}, value: string): T | undefined {
return (Object.values(enm) as unknown as string[]).includes(value)
? value as unknown as T
: undefined;
}
enumFromStringValue(Color, "RD"); // Color.Red
enumFromStringValue(Color, "UNKNOWN"); // undefined
enumFromStringValue(Color, "Red"); // undefined
我正在寻找一个答案,可以从字符串中获得enum,但在我的情况下,enum值有不同的字符串值对应。OP有一个简单的枚举颜色,但我有一些不同的东西:
enum Gender {
Male = 'Male',
Female = 'Female',
Other = 'Other',
CantTell = "Can't tell"
}
当你试图解决性别问题时。CantTell与"Can't tell"字符串,它返回未定义的原始答案。
另一个答案
基本上,受到这个答案的强烈启发,我想出了另一个答案:
export const stringToEnumValue = <ET, T>(enumObj: ET, str: string): T =>
(enumObj as any)[Object.keys(enumObj).filter(k => (enumObj as any)[k] === str)[0]];
笔记
我们使用筛选器的第一个结果,假设客户端从枚举中传递一个有效的字符串。如果不是这样,则返回undefined。 我们将enumObj转换为any,因为在TypeScript 3.0+(目前使用TypeScript 3.5)中,enumObj被解析为unknown。
使用实例
const cantTellStr = "Can't tell";
const cantTellEnumValue = stringToEnumValue<typeof Gender, Gender>(Gender, cantTellStr);
console.log(cantTellEnumValue); // Can't tell
注意:而且,正如有人在评论中指出的那样,我还想使用noImplicitAny。
更新版本
没有对任何正确类型的强制转换。
export const stringToEnumValue = <T, K extends keyof T>(enumObj: T, value: string): T[keyof T] | undefined =>
enumObj[Object.keys(enumObj).filter((k) => enumObj[k as K].toString() === value)[0] as keyof typeof enumObj];
此外,更新版本有一个更简单的方法来调用它,更可读:
stringToEnumValue(Gender, "Can't tell");