如何获取TypeScript枚举条目的名称?

Cal*_*ale 253 enums typescript

我想知道如何迭代TypeScript枚举和每个枚举的符号名称.

例如,

enum myEnum { entry1, entry2 }

for (var entry in myEnum) { 
    // use entry's name here, e.g., "entry1"
}
Run Code Online (Sandbox Code Playgroud)

sha*_*m02 260

虽然已经提供了答案,但几乎没有人指出这些文档

这是一个片段

enum Enum {
    A
}
let nameOfA = Enum[Enum.A]; // "A"
Run Code Online (Sandbox Code Playgroud)

  • 它还说"请记住,字符串枚举成员根本不会生成反向映射." (30认同)
  • 在 JS 中,enum 是一个 `[value]: name` 的对象,因此你可以获得像 `Object.keys(enum)` 这样的所有值,所有名称 `Object.values(enum)` 并使用 `for( 一次性迭代) const [值,名称] of Object.entries(enum)) { ... }`。请注意,当您获取值时,它们将是字符串,而不是您期望的数字(因为在 JS 中对象的键是字符串)。 (4认同)
  • 我不明白这如何回答所提出的问题。是的,这里所陈述的事实是正确的,人们可以从中推断出答案,但没有直接的答案。 (4认同)
  • 显示此枚举中的“0”或“1”怎么样?`导出枚举 Octave { ZERO = 0, ONE = 1 }` (3认同)
  • 循环遍历值怎么样? (3认同)
  • 如果您将枚举命名为 Enum 以外的其他名称,会更清楚 (2认同)

Jud*_*ngo 209

您发布的代码将起作用; 它将打印出枚举的所有成员,包括枚举成员的值.例如,以下代码:

enum myEnum { bar, foo }

for (var enumMember in myEnum) {
   console.log("enum member: ", enumMember);
}
Run Code Online (Sandbox Code Playgroud)

将打印以下内容:

Enum member: 0
Enum member: 1
Enum member: bar
Enum member: foo
Run Code Online (Sandbox Code Playgroud)

如果您只想要成员名而不是值,则可以执行以下操作:

for (var enumMember in myEnum) {
   var isValueProperty = parseInt(enumMember, 10) >= 0
   if (isValueProperty) {
      console.log("enum member: ", myEnum[enumMember]);
   }
}
Run Code Online (Sandbox Code Playgroud)

这将打印出名称:

Enum成员:酒吧

Enum成员:foo

警告:这稍微依赖于实现细节:TypeScript将枚举值编译为JS对象,枚举值为对象的成员.如果TS决定将来实施它们不同,上述技术可能会破裂.

  • 需要明确的是,上述答案仍然适用于TS 2.3.但是,如果你使用"const enum"而不仅仅是"enum",那么它才会起作用.使用const enum基本上告诉TS进行搜索和替换; 在您使用MyEnum.Foo的每个地方,它都将被替换为相应的数值. (16认同)

Rya*_*ugh 52

假设您遵守规则并仅生成具有数值的枚举,则可以使用此代码.这正确地处理了您的名称恰好是有效数字的情况

enum Color {
    Red,
    Green,
    Blue,
    "10" // wat
}

var names: string[] = [];
for(var n in Color) {
    if(typeof Color[n] === 'number') names.push(n);
}
console.log(names); // ['Red', 'Green', 'Blue', '10']
Run Code Online (Sandbox Code Playgroud)


Mic*_*son 43

对我来说,更简单,实用和直接的方式来理解发生了什么,是以下枚举:

enum colors { red, green, blue };
Run Code Online (Sandbox Code Playgroud)

将基本上转换为:

var colors = { red: 0, green: 1, blue: 2,
               [0]: "red", [1]: "green", [2]: "blue" }
Run Code Online (Sandbox Code Playgroud)

因此,以下情况属实:

colors.red === 0
colors[colors.red] === "red"
colors["red"] === 0
Run Code Online (Sandbox Code Playgroud)

这创建了一种简单的方法来获取枚举的名称,如下所示:

var color: colors = colors.red;
console.log("The color selected is " + colors[color]);
Run Code Online (Sandbox Code Playgroud)

它还创建了一种将字符串转换为枚举值的好方法.

var colorName: string = "green";
var color: colors = colors.red;
if (colorName in colors) color = colors[colorName];
Run Code Online (Sandbox Code Playgroud)

上面两种情况是更常见的情况,因为通常您对特定值的名称更感兴趣并以通用方式序列化值.


Sim*_*mon 36

如果您只搜索名称并稍后迭代使用:

Object.keys(myEnum).map(key => myEnum[key]).filter(value => typeof value === 'string') as string[];
Run Code Online (Sandbox Code Playgroud)

  • 或者使用ES2017 lib:`Object.values(myEnum).filter(value => typeof value ==='string')as string [];` (10认同)
  • 或者只是 Object.values(myEnum).filter(isNaN) as string[]; (2认同)
  • “Object.keys(myEnum)”不足以获取枚举对象中包含键名的数组吗? (2认同)

Phi*_*nci 23

使用当前的TypeScript版本1.8.9,我使用键入的枚举:

export enum Option {
    OPTION1 = <any>'this is option 1',
    OPTION2 = <any>'this is option 2'
}
Run Code Online (Sandbox Code Playgroud)

与此Javascript对象中的结果:

Option = {
    "OPTION1": "this is option 1",
    "OPTION2": "this is option 2",
    "this is option 1": "OPTION1",
    "this is option 2": "OPTION2"
}
Run Code Online (Sandbox Code Playgroud)

所以我必须通过键和值查询,只返回值:

let optionNames: Array<any> = [];    
for (let enumValue in Option) {
    let optionNameLength = optionNames.length;

    if (optionNameLength === 0) {
        this.optionNames.push([enumValue, Option[enumValue]]);
    } else {
        if (this.optionNames[optionNameLength - 1][1] !== enumValue) {
            this.optionNames.push([enumValue, Option[enumValue]]);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到一个数组中的选项键:

optionNames = [ "OPTION1", "OPTION2" ];
Run Code Online (Sandbox Code Playgroud)


coy*_*yer 21

似乎这里的所有答案都不适用于strict-mode 中的字符串枚举。

考虑枚举为:

enum AnimalEnum {
  dog = "dog", cat = "cat", mouse = "mouse"
}
Run Code Online (Sandbox Code Playgroud)

访问它AnimalEnum["dog"]可能会导致如下错误:

Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof AnimalEnum'.ts(7053).

这种情况的正确解决方案,将其写为:

AnimalEnum["dog" as keyof typeof AnimalEnum]
Run Code Online (Sandbox Code Playgroud)

  • 当值与键不同时就不那么出色了 (8认同)

小智 19

作为打字稿2.4,枚举可以包含字符串intializers https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-4.html

这允许你写:

 enum Order {
      ONE = "First",
      TWO = "Second"
 }

console.log(`One is ${Order.ONE.toString()}`);
Run Code Online (Sandbox Code Playgroud)

得到这个输出:

一个是第一个

  • 它如何“迭代”“每个枚举符号名称”?这根本不是给定问题的答案。 (2认同)

Car*_*hos 16

这个解决方案也有效.

enum ScreenType {
    Edit = 1,
    New = 2,
    View = 4
}

var type: ScreenType = ScreenType.Edit;

console.log(ScreenType[type]); //Edit
Run Code Online (Sandbox Code Playgroud)

  • 为什么它为我打印“未定义”?任何想法? (2认同)

Val*_*nal 15

在 TypeScript 中,枚举被编译为 JavaScript 中的映射(以从键获取值):

enum MyEnum {
  entry0,
  entry1,
}

console.log(MyEnum['entry0']); // 0
console.log(MyEnum['entry1']); // 1
Run Code Online (Sandbox Code Playgroud)

它还创建一个反向映射(从值中获取键):

console.log(MyEnum[0]); // 'entry0'
console.log(MyEnum[0]); // 'entry1'
Run Code Online (Sandbox Code Playgroud)

因此,您可以通过执行以下操作来访问条目的名称:

console.log(MyEnum[MyEnum.entry0]); // 'entry0'
console.log(MyEnum[MyEnum.entry1]); // 'entry1'
Run Code Online (Sandbox Code Playgroud)

但是,字符串枚举在设计上没有反向映射(请参阅注释拉取请求),因为这可能会导致映射对象中的键和值之间发生冲突。

enum MyEnum {
  entry0 = 'value0',
  entry1 = 'value1',
}

console.log(MyEnum['value0']); // undefined
console.log(MyEnum['value1']); // undefined
Run Code Online (Sandbox Code Playgroud)

如果您想强制字符串枚举编译反向映射(然后必须确保所有键和值都不同),您可以使用以下技巧:

enum MyEnum {
  entry0 = <any>'value0',
  entry1 = <any>'value1',
}

console.log(MyEnum['value0']); // 'entry0'
console.log(MyEnum['value1']); // 'entry1'
console.log(MyEnum[MyEnum.entry0]); // 'entry0'
console.log(MyEnum[MyEnum.entry1]); // 'entry1'
Run Code Online (Sandbox Code Playgroud)


Abo*_*zlR 13

简而言之

如果您的enums情况如下:

export enum Colors1 {
  Red = 1,
  Green = 2,
  Blue = 3
}
Run Code Online (Sandbox Code Playgroud)

获取特定文本和值:

console.log(Colors1.Red); // 1 
console.log(Colors1[Colors1.Red]); // Red
Run Code Online (Sandbox Code Playgroud)

获取值和文本列表:

public getTextAndValues(e: { [s: number]: string }) {
  for (const enumMember in e) {
    if (parseInt(enumMember, 10) >= 0) {
      console.log(e[enumMember]) // Value, such as 1,2,3
      console.log(parseInt(enumMember, 10)) // Text, such as Red,Green,Blue
    }
  }
}
this.getTextAndValues(Colors1)
Run Code Online (Sandbox Code Playgroud)

如果您的enums情况如下:

export enum Colors2 {
  Red = "Red",
  Green = "Green",
  Blue = "Blue"
}
Run Code Online (Sandbox Code Playgroud)

获取特定文本和值:

console.log(Colors2.Red); // Red
console.log(Colors2["Red"]); // Red
Run Code Online (Sandbox Code Playgroud)

获取值和文本列表:

public getTextAndValues(e: { [s: string]: string }) {
  for (const enumMember in e) {
    console.log(e[enumMember]);// Value, such as Red,Green,Blue
    console.log(enumMember); //  Text, such as Red,Green,Blue
  }
}
this.getTextAndValues(Colors2)
Run Code Online (Sandbox Code Playgroud)

  • 不适用于字符串和异构枚举。通过“thsi”的外观,很容易暗示代码从未被编译过。 (4认同)
  • 我否决了它,因为它是错误的。数字枚举并不是唯一的枚举类型。我也不明白为什么数字必须是非负数。`enum A { B = -1 }` 完全有效。 (2认同)

Vol*_*mil 12

假设您有一个enum

export enum SCROLL_LABEL_OFFSET {
  SMALL = 48,
  REGULAR = 60,
  LARGE = 112
}
Run Code Online (Sandbox Code Playgroud)

您想要创建一个基于枚举的类型,而不仅仅是复制和粘贴。您可以使用 anenum来创建type这样的:

export type ScrollLabelOffset = keyof typeof SCROLL_LABEL_OFFSET;
Run Code Online (Sandbox Code Playgroud)

结果您将收到一个type可能值为'SMALL' | 'REGULAR' | 'LARGE'


man*_*nza 11

在这里找到的另一个有趣的解决方案是使用ES6 Map:

export enum Type {
  low,
  mid,
  high
}

export const TypeLabel = new Map<number, string>([
  [Type.low, 'Low Season'],
  [Type.mid, 'Mid Season'],
  [Type.high, 'High Season']
]);
Run Code Online (Sandbox Code Playgroud)

使用

console.log(TypeLabel.get(Type.low)); // Low Season
Run Code Online (Sandbox Code Playgroud)

  • 问题询问如何“迭代”枚举的键。这并不能回答问题。 (4认同)

Jef*_*Lau 8

ts-enum-util(github,npm)为您完成工作,并提供许多其他类型安全的实用程序.适用于字符串和数字枚举,正确忽略数字枚举的数字索引反向查找条目:

字符串枚举:

import {$enum} from "ts-enum-util";

enum Option {
    OPTION1 = 'this is option 1',
    OPTION2 = 'this is option 2'
}

// type: ("OPTION1" | "OPTION2")[]
// value: ["OPTION1", "OPTION2"]
const keys= $enum(Option).getKeys();

// type: Option[]
// value: ["this is option 1", "this is option 2"]
const values = $enum(Option).getValues();
Run Code Online (Sandbox Code Playgroud)

数字枚举:

enum Option {
    OPTION1,
    OPTION2
}

// type: ("OPTION1" | "OPTION2")[]
// value: ["OPTION1", "OPTION2"]
const keys= $enum(Option).getKeys();

// type: Option[]
// value: [0, 1]
const values = $enum(Option).getValues();
Run Code Online (Sandbox Code Playgroud)


Sla*_*lny 7

enum-values当我遇到同样的问题时你可以使用我写的包:

Git:枚举值

var names = EnumValues.getNames(myEnum);
Run Code Online (Sandbox Code Playgroud)

  • 您并没有真正回答这个问题,最好用代码/等来记录您的答案,但我确实发现该软件包很有用. (2认同)

kit*_*112 7

从typescript 2.4开始,枚举不再包含键作为成员.来自Typescript自述文件

需要注意的是,字符串初始化的枚举不能反向映射以获取原始枚举成员名称.换句话说,你不能写颜色["RED"]来获得字符串"红色".

我的解决方案

export const getColourKey = (value: string ) => {
    let colourKey = '';
    for (const key in ColourEnum) {
        if (value === ColourEnum[key]) {
            colourKey = key;
            break;
        }
    }
    return colourKey;
};
Run Code Online (Sandbox Code Playgroud)

  • 询问“获取每个枚举符号名称”的问题。这会按值查找特定的键。 (2认同)

Dmi*_*try 7

基于上面的一些答案,我提出了这种类型安全的功能签名:

export function getStringValuesFromEnum<T>(myEnum: T): keyof T {
  return Object.keys(myEnum).filter(k => typeof (myEnum as any)[k] === 'number') as any;
}
Run Code Online (Sandbox Code Playgroud)

用法:

enum myEnum { entry1, entry2 };
const stringVals = getStringValuesFromEnum(myEnum);
Run Code Online (Sandbox Code Playgroud)

的类型stringVals'entry1' | 'entry2'

看到它在行动


ASK*_*ASK 7

他们在官方文档中提供了一个称为“反向映射”的概念。它帮助了我:

https://www.typescriptlang.org/docs/handbook/enums.html#reverse-mappings

解决方案非常简单:

enum Enum {
 A,
}

let a = Enum.A;
let nameOfA = Enum[a]; // "A"
Run Code Online (Sandbox Code Playgroud)


Sha*_*mad 6

根据 TypeScript 文档,我们可以通过带有静态函数的 Enum 来做到这一点。

使用静态函数获取枚举名称

enum myEnum { 
    entry1, 
    entry2 
}

namespace myEnum {
    export function GetmyEnumName(m: myEnum) {
      return myEnum[m];
    }
}


now we can call it like below
myEnum.GetmyEnumName(myEnum.entry1);
// result entry1 
Run Code Online (Sandbox Code Playgroud)

要阅读有关带有静态函数的 Enum 的更多信息,请访问以下链接 https://basarat.gitbooks.io/typescript/docs/enums.html


Cha*_*nce 6

这里已经有很多答案,但我想无论如何我都会将我的解决方案扔到堆栈上。

TypeScript 游乐场

enum AccountType {
  Google = 'goo',
  Facebook = 'boo',
  Twitter = 'wit',
}

type Key = keyof typeof AccountType // "Google" | "Facebook" | "Twitter"

// this creates a POJO of the enum "reversed" using TypeScript's Record utility
const reversed = (Object.keys(AccountType) as Key[]).reduce((acc, key) => {
  acc[AccountType[key]] = key
  return acc
}, {} as Record<AccountType, string>)
Run Code Online (Sandbox Code Playgroud)

为了清楚起见:

/*
 * reversed == {
 *   "goo": "Google",
 *   "boo": "Facebook",
 *   "wit": "Twitter",
 * }
 * reversed[AccountType.Google] === "Google" 
 */
Run Code Online (Sandbox Code Playgroud)

TypeScript 记录参考

迭代:

for (const [key, value] of Object.entries(reversed)) {
  console.log(`${key}: ${value}`);
}
Run Code Online (Sandbox Code Playgroud)

一个很好的辅助函数:

const getAccountTypeName = (type: AccountType) => {
  return reversed[type]
};

// getAccountTypeName(AccountType.Twitter) === 'Twitter'
Run Code Online (Sandbox Code Playgroud)


pol*_*.ph 6

我厌倦了浏览不正确的答案,我自己做了。

  • 这个有测试。
  • 适用于所有类型的枚举。
  • 正确键入。
type EnumKeys<Enum> = Exclude<keyof Enum, number>

const enumObject = <Enum extends Record<string, number | string>>(e: Enum) => {
    const copy = {...e} as { [K in EnumKeys<Enum>]: Enum[K] };
    Object.values(e).forEach(value => typeof value === 'number' && delete copy[value]);
    return copy;
};

const enumKeys = <Enum extends Record<string, number | string>>(e: Enum) => {
    return Object.keys(enumObject(e)) as EnumKeys<Enum>[];
};

const enumValues = <Enum extends Record<string, number | string>>(e: Enum) => {
    return [...new Set(Object.values(enumObject(e)))] as Enum[EnumKeys<Enum>][];
};

enum Test1 { A = "C", B = "D"}
enum Test2 { A, B }
enum Test3 { A = 0, B = "C" }
enum Test4 { A = "0", B = "C" }
enum Test5 { undefined = "A" }
enum Test6 { A = "undefined" }
enum Test7 { A, B = "A" }
enum Test8 { A = "A", B = "A" }
enum Test9 { A = "B", B = "A" }

console.log(enumObject(Test1)); // {A: "C", B: "D"}
console.log(enumObject(Test2)); // {A: 0, B: 1}
console.log(enumObject(Test3)); // {A: 0, B: "C"}
console.log(enumObject(Test4)); // {A: "0", B: "C"}
console.log(enumObject(Test5)); // {undefined: "A"}
console.log(enumObject(Test6)); // {A: "undefined"}
console.log(enumObject(Test7)); // {A: 0,B: "A"}
console.log(enumObject(Test8)); // {A: "A", B: "A"}
console.log(enumObject(Test9)); // {A: "B", B: "A"}

console.log(enumKeys(Test1)); // ["A", "B"]
console.log(enumKeys(Test2)); // ["A", "B"]
console.log(enumKeys(Test3)); // ["A", "B"]
console.log(enumKeys(Test4)); // ["A", "B"]
console.log(enumKeys(Test5)); // ["undefined"]
console.log(enumKeys(Test6)); // ["A"]
console.log(enumKeys(Test7)); // ["A", "B"]
console.log(enumKeys(Test8)); // ["A", "B"]
console.log(enumKeys(Test9)); // ["A", "B"]

console.log(enumValues(Test1)); // ["C", "D"]
console.log(enumValues(Test2)); // [0, 1]
console.log(enumValues(Test3)); // [0, "C"]
console.log(enumValues(Test4)); // ["0", "C"]
console.log(enumValues(Test5)); // ["A"] 
console.log(enumValues(Test6)); // ["undefined"] 
console.log(enumValues(Test7)); // [0, "A"]
console.log(enumValues(Test8)); // ["A"]
console.log(enumValues(Test9)); // ["B", "A"]
Run Code Online (Sandbox Code Playgroud)

在线版。


arh*_*ect 6

数字枚举

enum MyNumericEnum {
 First = 1,
 Second = 2
}
Run Code Online (Sandbox Code Playgroud)

您需要先将其转换为数组:

const values = Object.values(MyNumericEnum);
// ['First', 'Second', 1, 2]
Run Code Online (Sandbox Code Playgroud)

如您所见,它包含键和值。钥匙先走。

之后,您可以检索其密钥:

values.slice(0, values.length / 2);
// ['First', 'Second']
Run Code Online (Sandbox Code Playgroud)

和价值观:

values.slice(values.length / 2);
// [1, 2]
Run Code Online (Sandbox Code Playgroud)

对于字符串枚举,您可以分别使用Object.keys(MyStringEnum)in order 获取键和Object.values(MyStringEnum)in order 获取值。

尽管提取混合 enum的键和值有些挑战性。


use*_*105 5

在所有情况下(即使值是字符串)对我有用的唯一解决方案如下:

var enumToString = function(enumType, enumValue) {
    for (var enumMember in enumType) {
        if (enumType[enumMember]==enumValue) return enumMember
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这将按值搜索枚举键。询问“获取每个枚举符号名称”的问题。 (2认同)

Arn*_*ria 5

我写了一个 EnumUtil 类,它通过枚举值进行类型检查:

export class EnumUtils {
  /**
   * Returns the enum keys
   * @param enumObj enum object
   * @param enumType the enum type
   */
  static getEnumKeys(enumObj: any, enumType: EnumType): any[] {
    return EnumUtils.getEnumValues(enumObj, enumType).map(value => enumObj[value]);
  }

  /**
   * Returns the enum values
   * @param enumObj enum object
   * @param enumType the enum type
   */
  static getEnumValues(enumObj: any, enumType: EnumType): any[] {
    return Object.keys(enumObj).filter(key => typeof enumObj[key] === enumType);
  }
}

export enum EnumType {
  Number = 'number',
  String = 'string'
}
Run Code Online (Sandbox Code Playgroud)

如何使用它:

enum NumberValueEnum{
  A= 0,
  B= 1
}

enum StringValueEnum{
  A= 'A',
  B= 'B'
}

EnumUtils.getEnumKeys(NumberValueEnum, EnumType.Number);
EnumUtils.getEnumValues(NumberValueEnum, EnumType.Number);

EnumUtils.getEnumKeys(StringValueEnum, EnumType.String);
EnumUtils.getEnumValues(StringValueEnum, EnumType.String);
Run Code Online (Sandbox Code Playgroud)

NumberValueEnum 键的结果:["A", "B"]

NumberValueEnum 值的结果:[0, 1]

StringValueEnumkeys 的结果:["A", "B"]

StringValueEnumvalues 的结果:["A", "B"]


Ale*_*rff 5

我通过搜索“TypeScript 迭代枚举键”发现了这个问题。所以我只想发布对我有用的解决方案。也许它也会对某人有所帮助。

我的情况如下:我想遍历每个枚举键,然后过滤一些键,然后访问一些对象,它的键作为枚举的计算值。所以这就是我在没有任何 TS 错误的情况下做到的。

    enum MyEnum = { ONE = 'ONE', TWO = 'TWO' }
    const LABELS = {
       [MyEnum.ONE]: 'Label one',
       [MyEnum.TWO]: 'Label two'
    }


    // to declare type is important - otherwise TS complains on LABELS[type]
    // also, if replace Object.values with Object.keys - 
    // - TS blames wrong types here: "string[] is not assignable to MyEnum[]"
    const allKeys: Array<MyEnum> = Object.values(MyEnum)

    const allowedKeys = allKeys.filter(
      (type) => type !== MyEnum.ONE
    )

    const allowedLabels = allowedKeys.map((type) => ({
      label: LABELS[type]
    }))
Run Code Online (Sandbox Code Playgroud)


小智 5

打字稿游乐场示例

enum TransactionStatus {
  SUBMITTED = 'submitted',
  APPROVED = 'approved',
  PAID = 'paid',
  CANCELLED = 'cancelled',
  DECLINED = 'declined',
  PROCESSING = 'processing',
}


let set1 = Object.entries(TransactionStatus).filter(([,value]) => value === TransactionStatus.SUBMITTED || value === TransactionStatus.CANCELLED).map(([key,]) => {
    return key
})


let set2 = Object.entries(TransactionStatus).filter(([,value]) => value === TransactionStatus.PAID || value === TransactionStatus.APPROVED).map(([key,]) => {
    return key
})

let allKeys = Object.keys(TransactionStatus)



console.log({set1,set2,allKeys})
Run Code Online (Sandbox Code Playgroud)