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

时间:2013-08-07 19:01:57

标签: enums typescript

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

如,

enum myEnum { entry1, entry2 }

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

34 个答案:

答案 0 :(得分:192)

虽然答案已经提供,但几乎没有人指出docs

这是一个片段

String contactId ="10001"; // change it as your IDs
    if (mBitmap != null) {
                // Picture
                try {
                    ByteArrayOutputStream image = new ByteArrayOutputStream();
                    mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, image);

                    Uri rawContactUri = null;
                    Cursor rawContactCursor = managedQuery(
                            ContactsContract.RawContacts.CONTENT_URI,
                            new String[]{ContactsContract.RawContacts._ID},
                            ContactsContract.RawContacts.CONTACT_ID + " = " + contactId,
                            null,
                            null);
                    if (!rawContactCursor.isAfterLast()) {
                        rawContactCursor.moveToFirst();
                        rawContactUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon().appendPath("" + rawContactCursor.getLong(0)).build();
                    }
                    rawContactCursor.close();

                    ContentValues values = new ContentValues();
                    int photoRow = -1;
                    String where111 = ContactsContract.Data.RAW_CONTACT_ID + " == " +
                            ContentUris.parseId(rawContactUri) + " AND " + ContactsContract.Data.MIMETYPE + "=='" +
                            ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'";
                    Cursor cursor = managedQuery(
                            ContactsContract.Data.CONTENT_URI,
                            null,
                            where111,
                            null,
                            null);
                    int idIdx = cursor.getColumnIndexOrThrow(ContactsContract.Data._ID);
                    if (cursor.moveToFirst()) {
                        photoRow = cursor.getInt(idIdx);
                    }

                    cursor.close();


                    values.put(ContactsContract.Data.RAW_CONTACT_ID,
                            ContentUris.parseId(rawContactUri));
                    values.put(ContactsContract.Data.IS_SUPER_PRIMARY, 1);
                    values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, image.toByteArray());
                    values.put(ContactsContract.Data.MIMETYPE,
                            ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
                    if (photoRow >= 0) {
                        getContentResolver().update(
                                ContactsContract.Data.CONTENT_URI,
                                values,
                                ContactsContract.Data._ID + " = " + photoRow, null);
                    } else {
                        getContentResolver().insert(
                                ContactsContract.Data.CONTENT_URI,
                                values);
                    }
                } catch (Exception e) {
                    Log.e("!_@@Image_Exception", e + "");
                }
            }
 try {
            getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
       } catch (Exception e) {
            Log.e("@@@@@UPLOADERR", e + "");
        }

答案 1 :(得分:172)

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

enum myEnum { bar, foo }

for (var enumMember in myEnum) {
   console.log("enum member: ", enumMember);
}

将打印以下内容:

Enum member: 0
Enum member: 1
Enum member: bar
Enum member: foo

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

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

这将打印出名称:

  

枚举成员:bar

     

枚举成员:foo

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

答案 2 :(得分:51)

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

的情况
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']

答案 3 :(得分:39)

对我来说,一个更简单,实用和直接的方式来理解正在发生的事情,是以下列举:

enum colors { red, green, blue };

将基本上转换为:

var colors = { red: 0, green: 1, blue: 2,
               [0]: "red", [1]: "green", [2]: "blue" }

因此,以下情况属实:

colors.red === 0
colors[colors.red] === "red"
colors["red"] === 0

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

var color: colors = colors.red;
console.log("The color selected is " + colors[color]);

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

var colorName: string = "green";
var color: colors = colors.red;
if (colorName in colors) color = colors[colorName];

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

答案 4 :(得分:28)

如果您只搜索名称并稍后重复使用:

Object.keys(myEnum).map(key => myEnum[key]).filter(value => typeof value === 'string') as string[];

答案 5 :(得分:15)

似乎所有答案都无法在strict模式下使用字符串枚举。

将枚举视为:

enum AnimalEnum {
  dog = "dog", cat = "cat", mouse = "mouse"
}

使用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]

答案 6 :(得分:12)

此解决方案也有效。

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

var type: ScreenType = ScreenType.Edit;

console.log(ScreenType[type]); //Edit

答案 7 :(得分:10)

从Typescript 2.4开始,枚举可以包含字符串初始化符https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-4.html

这允许您编写:

Cookie

并获得以下输出:

  

一个是第一位

答案 8 :(得分:7)

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

Git: enum-values

var names = EnumValues.getNames(myEnum);

答案 9 :(得分:7)

简而言之

如果您的 export enum Colors1 { Red = 1, Green = 2, Blue = 3 } 如下所示:

console.log(Colors1.Red); // 1 
console.log(Colors1[Colors1.Red]); // Red

获取特定文本和值:

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)

获取值和文本列表:

enums

如果您的 export enum Colors2 { Red = "Red", Green = "Green", Blue = "Blue" } 如下所示:

console.log(Colors2.Red); // Red
console.log(Colors2["Red"]); // Red

获取特定文本和值:

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)

获取值和文本列表:

{{1}}

答案 10 :(得分: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"]

Online version.

答案 11 :(得分:6)

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

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

用法:

enum myEnum { entry1, entry2 };
const stringVals = getStringValuesFromEnum(myEnum);

stringVals的类型为'entry1' | 'entry2'

See it in action

答案 12 :(得分:5)

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

String enum:

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();

数字枚举:

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();

答案 13 :(得分:5)

另一个有趣的解决方案founded here使用的是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']
]);

使用

console.log(TypeLabel.get(Type.low)); // Low Season

答案 14 :(得分:5)

从typescript 2.4开始,枚举不再包含作为成员的键。 source from Typescript readme

  

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

我的解决方案:

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

答案 15 :(得分:4)

如果您有枚举

enum Diet {
  KETO = "Ketogenic",
  ATKINS = "Atkins",
  PALEO = "Paleo",
  DGAF = "Whatever"
}

然后您可以获取键和值,如:

Object.keys(Diet).forEach((d: Diet) => {
  console.log(d); // KETO
  console.log(Diet[d]) // Ketogenic
});

答案 16 :(得分:3)

要获取枚举值列表,您必须使用:

enum AnimalEnum {
  DOG = "dog", 
  CAT = "cat", 
  MOUSE = "mouse"
}

Object.values(AnimalEnum);

答案 17 :(得分:2)

这里已经有很多答案,但是我想我还是会将解决方案扔到堆栈上。

TypeScript Playground

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>)

为清晰起见:

/*
 * reversed == {
 *   "goo": "Google",
 *   "boo": "Facebook",
 *   "wit": "Twitter",
 * }
 * reversed[AccountType.Google] === "Google" ?
 */

TypeScript Record的引用

一个很好的助手功能:

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

// getAccountTypeName(AccountType.Twitter) === 'Twitter'

答案 18 :(得分:2)

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

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

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

如何使用它:

enum TestEnum{
  A= 0,
  B= 1
}

EnumUtils.getEnumKeys(TestEnum, "number");
EnumUtils.getEnumValues(TestEnum, "number");

键结果:[“ A”,“ B”]

结果取值:[0,1]

答案 19 :(得分:2)

古老的问题,但是,为什么不使用const对象映射?

代替这样做:

enum Foo {
    BAR = 60,
    EVERYTHING_IS_TERRIBLE = 80
}

console.log(Object.keys(Foo))
// -> ["60", "80", "BAR", "EVERYTHING_IS_TERRIBLE"]
console.log(Object.values(Foo))
// -> ["BAR", "EVERYTHING_IS_TERRIBLE", 60, 80]

执行此操作(注意as const强制转换):

const Foo = {
    BAR: 60,
    EVERYTHING_IS_TERRIBLE: 80
} as const

console.log(Object.keys(Foo))
// -> ["BAR", "EVERYTHING_IS_TERRIBLE"]
console.log(Object.values(Foo))
// -> [60, 80]

答案 20 :(得分:2)

我认为最好的方法是只声明所需的枚举值。这样访问它们既干净又漂亮(每次)。

enum myEnum { entry1 = 'VALUE1', entry2 = 'VALUE2' }

for (var entry in myEnum) { 
    console.log(entry);
}

将产生:

VALUE1
VALUE2

答案 21 :(得分:2)

根据打字稿文档,我们可以通过带有静态函数的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 

有关使用静态函数的Enum的更多信息,请点击以下链接 https://basarat.gitbooks.io/typescript/docs/enums.html

答案 22 :(得分:1)

我编写了一个帮助函数来枚举枚举:

static getEnumValues<T extends number>(enumType: {}): T[] {
  const values: T[] = [];
  const keys = Object.keys(enumType);
  for (const key of keys.slice(0, keys.length / 2)) {
    values.push(<T>+key);
  }
  return values;
}

用法:

for (const enumValue of getEnumValues<myEnum>(myEnum)) {
  // do the thing
}

该函数返回可以轻松枚举的内容,并且还强制转换为枚举类型。

答案 23 :(得分:1)

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

var enumToString = function(enumType, enumValue) {
    for (var enumMember in enumType) {
        if (enumType[enumMember]==enumValue) return enumMember
    }
}

答案 24 :(得分:1)

我希望这个问题仍然相关。我使用这样的功能:

function enumKeys(target: Record<string, number|string>): string[] {
  const allKeys: string[] = Object.keys(target);
  const parsedKeys: string[] = [];

  for (const key of allKeys) {
    const needToIgnore: boolean
      = target[target[key]]?.toString() === key && !isNaN(parseInt(key));

    if (!needToIgnore) {
      parsedKeys.push(key);
    }
  }

  return parsedKeys;
}

function enumValues(target: Record<string, number|string>): Array<string|number> {
  const keys: string[] = enumKeys(target);
  const values: Array<string|number> = [];

  for (const key of keys) {
    values.push(target[key]);
  }

  return values;
}

示例:

enum HttpStatus {
  OK,
  INTERNAL_ERROR,
  FORBIDDEN = 'FORBIDDEN',
  NOT_FOUND = 404,
  BAD_GATEWAY = 'bad-gateway'
}


console.log(enumKeys(HttpStatus));
// > ["OK", "INTERNAL_ERROR", "FORBIDDEN", "NOT_FOUND", "BAD_GATEWAY"] 

console.log(enumValues(HttpStatus));
// > [0, 1, "FORBIDDEN", 404, "bad-gateway"]

答案 25 :(得分:1)

我觉得这个解决方案更优雅:

for (let val in myEnum ) {

 if ( isNaN( parseInt( val )) )
     console.log( val );
}

显示:

bar 
foo

答案 26 :(得分:1)

您可以通过以下方式从 Enum 中获取名称数组:

      headless: true,
      ignoreHTTPSErrors: true,
      args: [
        "--proxy-server='direct://'",
        '--proxy-bypass-list=*',
        '--disable-gpu',
        '--disable-dev-shm-usage',
        '--disable-setuid-sandbox',
        '--no-first-run',
        '--no-sandbox',
        '--no-zygote',
        '--single-process',
        '--ignore-certificate-errors',
        '--ignore-certificate-errors-spki-list',
        '--enable-features=NetworkService'
      ]
    }); 

答案 27 :(得分:0)

我通过搜索“遍历枚举键的打字稿”发现了这个问题。所以我只想发布对我而言适用的解决方案。也许也会对某人有所帮助。

我的情况如下:我想遍历每个枚举键,然后过滤一些键,然后访问一些具有键的对象,这些键具有来自枚举的计算值。所以这就是我的做法,没有任何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 !== InsuranceType.OSAGO
    )

    const allowedLabels = allowedKeys.map((type) => ({
      label: LABELS[type]
    }))

答案 28 :(得分:0)

使用当前版本的TypeScript,您可以使用诸如此类的功能将Enum映射到您选择的记录。请注意,您无法使用这些函数定义字符串值,因为它们会查找具有数字值的键。

Office.CustomXMLParts settingsXmlParts = presentation.CustomXMLParts.SelectByNamespace("Document.Settings");
foreach (var settingsXmlPart in settingsXmlParts)
     settingsXmlPart.Delete();

答案 29 :(得分:0)

我的枚举是这样的:

export enum UserSorting {
    SortByFullName = "Sort by FullName", 
    SortByLastname = "Sort by Lastame", 
    SortByEmail = "Sort by Email", 
    SortByRoleName = "Sort by Role", 
    SortByCreatedAt = "Sort by Creation date", 
    SortByCreatedBy = "Sort by Author", 
    SortByUpdatedAt = "Sort by Edit date", 
    SortByUpdatedBy = "Sort by Editor", 
}

这样返回 undefined

UserSorting[UserSorting.SortByUpdatedAt]

要解决此问题,我选择了另一种使用管道的方法:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
    name: 'enumKey'
})
export class EnumKeyPipe implements PipeTransform {

  transform(value, args: string[] = null): any {
    let enumValue = args[0];
    var keys = Object.keys(value);
    var values = Object.values(value);
    for (var i = 0; i < keys.length; i++) {
      if (values[i] == enumValue) {
        return keys[i];
      }
    }
    return null;
    }
}

并使用它:

return this.enumKeyPipe.transform(UserSorting, [UserSorting.SortByUpdatedAt]);

答案 30 :(得分:0)

在这里有很多答案,考虑到尽管这个问题已有7年之久,但我还是查了一下,我想这里还会有更多问题。这是我的解决方案,它比其他解决方案要简单一些,它可以处理仅数字/纯文本/混合值枚举。

      "apiVersion": "2018-02-14",

答案 31 :(得分:0)

如果它是您的 enum 并且您定义如下所示,名称和值是相同的,它将直接为您提供条目的名称。

enum myEnum { 
    entry1="entry1", 
    entry2="entry2"
 }

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

答案 32 :(得分:0)

这对于基于键值的枚举更有效:

enum yourEnum {
  ["First Key"] = "firstWordValue",
  ["Second Key"] = "secondWordValue"
}

Object.keys(yourEnum)[Object.values(yourEnum).findIndex(x => x === yourValue)]
// Result for passing values as yourValue
// FirstKey
// SecondKey

答案 33 :(得分:-1)

这不是您所提问题的确切答案,但这是解决您的问题的一个窍门。

export module Gender {

  export enum Type {
    Female = 1,
    Male = 2
  };

  export const List = Object.freeze([
    { Female: Type.Female },
    { Male: Type.Male }
  ]);

}

您可以根据需要扩展列表模型。

export const List = Object.freeze([
    { Female: { key: 'Female', value: Type.Female } },
    { Male: { key: 'Male', value: Type.Male } }
  ]);

现在,您可以通过以下方式使用它:

for(let gender of Gender.List){
  console.log(gender.Female.key);
  console.log(gender.Female.value);
}

或:

if(i === Gender.Type.Male){
  console.log("I'm a man.");
}