Ami*_*abh 247 typescript
我在TypeScript中定义了以下枚举?
enum Color{
    Red, Green
}
现在在我的函数中,我收到颜色作为字符串.我试过以下代码:
var green= "Green";
var color : Color = <Color>green; // Error: can't convert string to enum
如何将该值转换为枚举?
bas*_*rat 353
TypeScript 0.9中的枚举是基于字符串+数字的.对于简单的转换,您不需要类型断言:
enum Color{
    Red, Green
}
// To String
 var green: string = Color[Color.Green];
// To Enum / number
var color : Color = Color[green];
我在OSS书中有关于此和其他Enum模式的文档:https://basarat.gitbooks.io/typescript/content/docs/enums.html
Vic*_*tor 95
从Typescript 2.1开始,枚举中的字符串键是强类型的.keyof typeof用于获取有关可用字符串键的信息(1):
enum Color{
    Red, Green
}
let typedColor: Color = Color.Green;
let typedColorString: keyof typeof Color = "Green";
// Error "Black is not assignable ..." (indexing using Color["Black"] will return undefined runtime)
typedColorString = "Black";
// Error "Type 'string' is not assignable ..." (indexing works runtime)
let letColorString = "Red";
typedColorString = letColorString;
// Works fine
typedColorString = "Red";
// Works fine
const constColorString = "Red";
typedColorString = constColorString
// Works fine (thanks @SergeyT)
let letColorString = "Red";
typedColorString = letColorString as keyof typeof Color;
typedColor = Color[typedColorString];
https://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types
ale*_*nia 72
如果您为枚举提供字符串值,则直接转换就可以了。
enum Color {
  Green = "Green",
  Red = "Red"
}
const color = "Green";
const colorEnum = color as Color;
Nic*_* N. 44
如果您使用打字稿:上面的许多解决方案可能不起作用或过于复杂。
情况:字符串与枚举值不同(大小写不同)
enum Color {
  Green = "green",
  Red = "red"
}
只需使用:
const color = "green" as Color
请注意,这并不能保证枚举有效。
Art*_*tru 27
如果您确定输入字符串与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为<any>类型,则tsc将显示错误
元素隐式具有"任何"类型,因为索引表达式不是"数字"类型.
这意味着默认TS Enum类型使用数字索引,即
 let c = Color[0]不使用字符串索引let c = Color["string"].这是Microsoft团队对更一般的问题对象字符串索引的已知限制.
Sly*_*nal 26
本说明涉及巴萨拉特的答案,而不是原始问题.
我在我自己的项目中遇到了一个奇怪的问题,即编译器使用相当于此代码的大小相当于"无法将字符串转换为颜色"的错误:
var colorId = myOtherObject.colorId; // value "Green";
var color: Color = <Color>Color[colorId]; // TSC error here: Cannot convert string to Color.
我发现编译器类型推理变得混乱,它认为这colorId是一个枚举值而不是ID.要解决这个问题,我必须将ID转换为字符串:
var colorId = <string>myOtherObject.colorId; // Force string value here
var color: Color = Color[colorId]; // Fixes lookup here.
我不确定是什么原因引起了这个问题,但我会在这里留下这个说明以防万一我遇到同样的问题.
Ami*_*abh 22
使用以下代码使其工作.
var green= "Green";
var color : Color= <Color>Color[green];
小智 14
我也遇到了相同的编译器错误.只是Sly_cardinal方法的略微变化.
var color: Color = Color[<string>colorId];
Jon*_*nas 14
enum Color{
    Red, Green
}
// To String
 var green: string = Color[Color.Green];
// To Enum / number
var color : Color = Color[green as keyof typeof Color]; //Works with --noImplicitAny
此示例可--noImplicitAny在TypeScript中使用
来源:
https  : //github.com/Microsoft/TypeScript/issues/13775#issuecomment-276381229 https://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types
for*_*d04 13
enum Color { Red, Green }
const c1 = Color["Red"]
const redStr = "Red" // important: use `const`, not mutable `let`
const c2 = Color[redStr]
const redStrWide: string = "Red" // wide, unspecific typed string
const c3 = Color[redStrWide as keyof typeof Color]
const isEnumName = <T>(str: string, _enum: T): str is Extract<keyof T, string> =>
    str in _enum
const enumFromName = <T>(name: string, _enum: T) => {
    if (!isEnumName(name, _enum)) throw Error() // here fail fast as an example
    return _enum[name]
}
const c4 = enumFromName(redStrWide, Color)
字符串枚举没有反向映射(与数字枚举相反)。我们可以创建一个查找助手来将枚举值字符串转换为枚举类型:
enum ColorStr { Red = "red", Green = "green" }
const c5_by_name = ColorStr["Red"] // ? this works
const c5_by_value_error = ColorStr["red"] // ? , but this not
const enumFromValue = <T extends Record<string, string>>(val: string, _enum: T) => {
    const enumName = (Object.keys(_enum) as Array<keyof T>).find(k => _enum[k] === val)
    if (!enumName) throw Error() // here fail fast as an example
    return _enum[enumName]
}
const c5 = enumFromValue("red", ColorStr)
elb*_*aid 12
我正在寻找一个可以enum从 a 中得到 an 的答案string,但在我的例子中,枚举值具有不同的字符串值对应物。OP 有一个简单的 enum for Color,但我有一些不同的东西:
enum Gender {
  Male = 'Male',
  Female = 'Female',
  Other = 'Other',
  CantTell = "Can't tell"
}
当您尝试Gender.CantTell使用"Can't tell"字符串解析时,它会返回undefined原始答案。
基本上,我想出了另一个答案,受到这个答案的强烈启发:
export const stringToEnumValue = <ET, T>(enumObj: ET, str: string): T =>
  (enumObj as any)[Object.keys(enumObj).filter(k => (enumObj as any)[k] === str)[0]];
filter,假设客户端从枚举传递一个有效的字符串。如果不是这种情况,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.
没有any强制转换和正确的打字。
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");
Fla*_*ken 10
长话短说:\n或者:
\n首先,枚举是人类可读的名称和值之间的映射,这就是它的用途。
\n默认值:\nTS 默认情况下将确保您为枚举的定义键拥有唯一的值。
\n这
\nenum Color {\n    Red, Green\n}\n相当于
\nenum Color {\n    Red = 0,\n    Green = 1\n}\n两者的转译后的 js 代码将是
\n"use strict";\nvar Color;\n(function (Color) {\n    Color[Color["Red"] = 0] = "Red";\n    Color[Color["Green"] = 1] = "Green";\n})(Color || (Color = {}));\n由于这是不可读的,因此创建后的结果对象如下:
\n{0: \'Red\', 1: \'Green\', Red: 0, Green: 1}\n该对象具有字符串和数字属性(不能有任何冲突,因为您不能将枚举键定义为数字)。TS 足够酷,可以生成一个包含映射 key -> value 和value -> key的对象。
\n感谢上帝,这是一个双射映射,即每个唯一值都有它的唯一键(因此反之亦然)
\n那么麻烦来了,如果我强制使用相同的值怎么办?
\nenum Color {\n    Red = 0,\n    Green = 0\n}\n这是创建的 js 对象的结果
\n{0: \'Green\', Red: 0, Green: 0}\n我们不再有双射(这是surjectif),没有神奇的映射0 : [\'Green\', \'Red\']。只是0 : \'Green\'我们失去了0 : \'Red\'
要点:当值是数字时,TS 总是会尝试放置反向映射(值 -> 键)。
\n现在您可能知道,您还可以在枚举中定义字符串值,让我们仅将绿色值更改为“绿色”
\nenum Color {\n    Red = 0,\n    Green = "GREEN"\n}\n这是生成的 js 对象
\n{0: \'Red\', Red: 0, Green: \'GREEN\'}\n正如您所看到的,Typescript 不会生成映射值 -> 键。\n它也不会生成,因为您最终可能会遇到值和键名称之间的冲突。请记住:键不能是数字,因此当值是数字时,不存在冲突的风险。
\n这让您明白不应依赖枚举的值 -> 键映射。该映射可能根本不存在或不准确。
\n同样,枚举是且仅应被视为人类可读的值名称。在某些情况下,ts 甚至根本不会生成任何反向映射。当您定义枚举常量时就是这种情况。
\nconst 枚举是纯编译时枚举,TS 将在转译时用其对应的值替换枚举的使用
\n例如:
\nconst enum Color {\n    Red = 0,\n    Green = "GREEN"\n}\n被转译为
\n"use strict";\n所以只是说 \xe2\x80\xa6 没什么,因为“使用严格”;甚至与我们写的内容无关。
\n这是相同的示例及其用法:
\nconst enum Color {\n    Red = 0,\n    Green = "GREEN"\n}\nconsole.log(Color.Green);\n被转译为
\n"use strict";\nconsole.log("GREEN" /* Green */);\n正如您所看到的,Color.Green 被转译器替换为“GREEN”。
\n那么回到最初的问题,如何将字符串转换为枚举?
\n解析器解决方案: \n我很抱歉,但我推荐的唯一干净的方法是编写一个函数,使用 switch case 是实现此目的的聪明方法。
\nfunction parseColorName(color: string): Color {\n  switch (color) {\n    case \'Red\': return Color.Red;\n    case \'Green\': return Color.Green;\n    default: throw new Error(\'unknown color\');\n  }\n}\n自定义枚举解决方案:
\n请注意,TS 枚举是不透明的,这意味着编译器无法正确键入值。出于这个原因(特别是当您需要使用反向映射时),我建议您自己进行枚举,如下所示:
\nexport const ColorType = {\n  RED: \'Red\',\n  GREEN: \'Green\',\n} as const;\n\nexport type ColorType = typeof ColorType[keyof typeof ColorType];\n以下是安全的(color只能取有效的已知值)。简而言之,您依赖于字符串联合而不是枚举值。
const color: ColorType= "Green";\n// And if you need to create a color from the enum like value:\nconst anotherColor: ColorType = ColorType.RED;\n如果typescript编译器知道变量的类型是字符串而不是这个
let colorName : string = "Green";
let color : Color = Color[colorName];
否则你应该显式地将其转换为字符串(以避免编译器警告)
let colorName : any = "Green";
let color : Color = Color["" + colorName];
在运行时,两种解决方案都可以
几乎所有答案都使用不安全的强制转换(as或is)。这个没有:
enum Color {
    Red = "red",
    Green = "green"
}
const colorsMap = new Map<string,Color>(Object.values(Color).map((v) => [v,v]))
function parseColor(volumeData: string): Color | undefined {
    return colorsMap.get(volumeData)
}
const color = parseColor("red")
我需要知道如何遍历枚举值(正在测试多个枚举的大量排列),我发现这很有效:
export enum Environment {
    Prod = "http://asdf.com",
    Stage = "http://asdf1234.com",
    Test = "http://asdfasdf.example.com"
}
Object.keys(Environment).forEach((environmentKeyValue) => {
    const env = Environment[environmentKeyValue as keyof typeof Environment]
    // env is now equivalent to Environment.Prod, Environment.Stage, or Environment.Test
}
来源:https : //blog.mikeski.net/development/javascript/typescript-enums-to-from-string/
小智 7
对于 TS 3.9.x
var color : Color = Color[green as unknown as keyof typeof Color];
如果您正在处理 TypeScript 4.1+ 和字符串枚举,并且您想要一个具有编译时和运行时安全性的简单字符串到枚举转换器,那么以下方法很有效:
export const asEnum = <
  T extends { [key: string]: string },
  K extends keyof T & string
>(
  enumObject: T,
  value: `${T[K]}`
): T[K] => {
  if (Object.values(enumObject).includes(value)) {
    return (value as unknown) as T[K];
  } else {
    throw new Error('Value provided was not found in Enum');
  }
};
enum Test {
  hey = 'HEY',
}
const test1 = asEnum(Test, 'HEY');   // no complaints here
const test2 = asEnum(Test, 'HE');    // compile-time error
const test3 = asEnum(Test, 'HE' as any); // run-time error
对于 Typescript >= 4,此代码有效:
enum Color{
    Red, Green
}
// Conversion :
var green= "Green";
var color : Color = green as unknown as Color; 
这个问题有很多混杂的信息,因此让我们在Nick的使用TypeScript的模型中使用枚举指南中介绍 TypeScript 2.x +的整个实现。
本指南适用于:正在创建客户端代码的人员,这些代码正在从服务器中提取一组已知字符串,这些字符串可以方便地在客户端上建模为Enum。
让我们从枚举开始。它看起来应该像这样:
export enum IssueType {
  REPS = 'REPS',
  FETCH = 'FETCH',
  ACTION = 'ACTION',
  UNKNOWN = 'UNKNOWN',
}
这里需要注意的两件事:
我们明确地将它们声明为字符串支持的枚举类型,这使我们可以使用字符串而不是其他一些无关的数字来实例化它们。
我们添加了一个服务器模型上可能存在或可能不存在的选项:UNKNOWN。可以按照undefined您的意愿进行处理,但是我希望尽可能避免| undefined使用type来简化处理。
拥有UNKNOWN案例的好处在于,您可以在代码中真正地看到它,并为未知枚举案例创建样式为鲜红色和闪烁的,因此您知道自己未正确处理某些事情。
您可能正在使用嵌入在另一个模型中的枚举,也可能单独使用,但您必须将JSON或XML(ha)中的字符串型枚举解析为强类型的枚举。当嵌入另一个模型中时,此解析器将驻留在类构造函数中。
parseIssueType(typeString: string): IssueType {
  const type = IssueType[typeString];
  if (type === undefined) {
    return IssueType.UNKNOWN;
  }
  return type;
}
如果枚举被正确解析,它将最终成为正确的类型。否则,undefined您可以拦截它并退回您的UNKNOWN案件。如果您希望将其undefined用作未知情况,则可以只返回尝试进行枚举解析的任何结果。
从那里开始,只需使用parse函数和使用新的强类型变量即可。
const strongIssueType: IssueType = parseIssueType('ACTION');
// IssueType.ACTION
const wrongIssueType: IssueType = parseIssueType('UNEXPECTED');
// IssueType.UNKNOWN
枚举
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;
    }
}
Typescript 3.9提案
enum Color{ RED, GREEN }
const color = 'RED' as Color;
容易peasy...柠檬挤压!
| 归档时间: | 
 | 
| 查看次数: | 178772 次 | 
| 最近记录: |