열거 형 항목의 이름을 얻는 방법?


314

TypeScript enum유형 을 반복하고 열거 된 각 심볼 이름을 가져 오려고합니다 .

enum myEnum { entry1, entry2 }

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

이 작은 열거 형 패키지는 목적 getAllEnumValuesgetAllEnumKeys목적을 위해
트랜스 앙

답변:


255

게시 한 코드가 작동합니다. 열거 형 멤버의 값을 포함하여 열거 형의 모든 멤버를 인쇄합니다. 예를 들어, 다음 코드는

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]);
   }
}

이름 만 출력됩니다.

열거 형 멤버 : 바

열거 형 멤버 : foo

주의 사항 : 이것은 구현 세부 사항에 약간 의존합니다. TypeScript는 열거 형 값이 객체의 멤버 인 JS 객체로 열거 형을 컴파일합니다. TS가 미래에 다른 방식으로 구현하기로 결정한 경우 위의 기술이 중단 될 수 있습니다.


23
분명히, 위의 답변은 여전히 ​​TS 2.3에서 작동합니다. 그러나 "enum"이 아닌 "const enum"을 사용하면 작동하지 않습니다. const enum을 사용하면 기본적으로 TS에게 검색 및 교체를 지시합니다. MyEnum.Foo를 사용할 때마다 해당 숫자 값으로 바뀝니다.
유다 가브리엘 히 망고

나는 생각 +enumMember >= 0해야한다 isFinite(+enumMember)부정적 또는 부동 소수점 값이 반대로 너무 매핑되는 때문이다. ( 놀이터 )
spenceryue

341

답변이 이미 제공되었지만 문서를 가리키는 사람은 거의 없습니다.

스 니펫이 있습니다.

enum Enum {
    A
}
let nameOfA = Enum[Enum.A]; // "A"

문자열 열거 형 멤버는 전혀 역방향 매핑을 생성하지 않습니다.


38
또한 "문자열 열거 형 멤버에는 역 매핑이 전혀 생성되지 않습니다."
jbojcic

1
어떻게 표시에 대한 0또는 1이 열거에서? export enum Octave { ZERO = 0, ONE = 1 }
Stephane

@jbojcic 상황에 관한 것 enum Enum {"A"}; let nameOfA = Enum[Enum.A];입니까? typescript@2.9.2 기준으로 그것은 나를 위해 잘 작동합니다 ...
ellockie

값을 반복하는 것은 어떻습니까?
시오 코

55

규칙을 고수하고 숫자 값을 가진 열거 형 만 생성한다고 가정하면이 코드를 사용할 수 있습니다. 이것은 우연히 유효한 숫자의 이름을 가진 경우를 올바르게 처리합니다.

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']

경고 현대의 타이프 스크립트 (tsc 2.5.2 atm)에서는 숫자 문자열을 키로 사용할 수 없습니다. Himango의 답변은 모든 경우를 다루고 단점이 없기 때문에 더 좋습니다.
srcspider

52

나를 위해 더 쉽고 실용적이며 직접적인 방법은 다음 열거 형입니다.

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];

위의 두 가지 상황은 훨씬 일반적인 상황입니다. 일반적으로 특정 값의 이름과 일반적인 방식으로 값을 직렬화하는 데 훨씬 더 관심이 있기 때문입니다.


49

이름 만 검색하고 나중에 반복하는 경우 다음을 사용하십시오.

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

13
또는 ES2017 lib를 사용하는 경우 :Object.values(myEnum).filter(value => typeof value === 'string') as string[];
None

나는 dict을 만들어야했고, 당신의 대답을 시작점으로 사용했습니다. 다른 사람이 필요하면Object.values(myEnum).filter(value => typeof value === 'string').map(key => { return {id: myEnum[key], type: key }; });
Fejs

25

현재 TypeScript 버전 1.8.9에서는 형식화 된 열거 형을 사용합니다.

export enum Option {
    OPTION1 = <any>'this is option 1',
    OPTION2 = <any>'this is option 2'
}

이 자바 스크립트 객체의 결과 :

Option = {
    "OPTION1": "this is option 1",
    "OPTION2": "this is option 2",
    "this is option 1": "OPTION1",
    "this is option 2": "OPTION2"
}

그래서 키와 값을 쿼리하고 값만 반환해야합니다.

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]]);
        }
    }
}

그리고 배열에서 옵션 키를받습니다.

optionNames = [ "OPTION1", "OPTION2" ];


17

이 솔루션도 작동합니다.

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

var type: ScreenType = ScreenType.Edit;

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

14

여기에있는 또 다른 흥미로운 해결책 은 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

10

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

숫자 열거 형 :

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

9

TypeScript 2.4부터는 열거 형에 더 이상 키가 멤버로 포함되지 않습니다. TypeScript 추가 정보 소스

주의 사항은 문자열로 초기화 된 열거 형을 역 열거하여 원래 열거 형 멤버 이름을 얻을 수 없다는 것입니다. 다시 말해, 문자열 "Red"를 얻기 위해 Colors [ "RED"]를 작성할 수 없습니다.

내 해결책 :

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

8

enum-values동일한 문제가 발생했을 때 작성한 패키지 를 사용할 수 있습니다 .

힘내 : 열거 형 값

var names = EnumValues.getNames(myEnum);

3
당신은 실제로 질문에 대답하지 않고 코드 / etc로 답을 문서화하는 것이 더 좋지만 패키지가 유용하다는 것을 알았습니다.
lucuma

7

위의 답변에 따라이 유형 안전 함수 서명을 생각해 냈습니다.

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'

실제로보기


1
(keyof T)[]대신에 함수가 반환되어야합니다 keyof T. 또한 export놀이터가 멈추는 것을 막습니다.
Joald

7

여기서 어떤 대답도 strict-mode의 string-enum과 작동하지 않는 것 같습니다 .

열거 형을 다음과 같이 고려하십시오.

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]

keyof와 함께 사용하기위한 훌륭한 솔루션 typeof! 다른 솔루션은 매우 불투명 해 보이지만 결국 Typescript는 DX-Enum의 개발자 경험
Shaung Cheng에서

5

내가 생각하는 가장 좋은 방법은 원하는 열거 형 값을 선언하는 것입니다. 그런 식으로 접근하는 것은 깨끗하고 예쁘다.

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

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

생산할 것이다 :

VALUE1
VALUE2

5

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 

정적 함수가있는 Enum에 대한 자세한 내용은 아래 링크를 참조하십시오 https://basarat.gitbooks.io/typescript/docs/enums.html


4

값이 문자열 인 경우에도 모든 경우에 적합한 유일한 솔루션 은 다음과 같습니다.

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

4

오래된 질문이지만 왜 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]

im이 틀렸다면 정정하되 console.log(Object.keys(Foo))첫 번째 예에서는 ["BAR", "EVERYTHING_IS_TERRIBLE"].. 만 반환합니다 .
Peter

@Peter 는 ts 놀이터를 살펴보고 콘솔을 열고 실행을 클릭하십시오. 나를 위해 적어도, 그것은 인쇄["60", "80", "BAR", "EVERYTHING_IS_TERRIBLE"]
가브리엘 드 올리베이라 Rohden

1
숫자에서 문자열로 변경하면 내가 기대 한 결과를 얻는 것이 재미 있고 재미있는 것 같습니다. 왜 typescript가 열거 형에서 문자열과 숫자를 다르게 처리하는지 모르겠습니다.
Peter

4

"TypeScript itumate over enum keys"를 검색하여이 질문을 찾았습니다. 그래서 나는 단지 내 경우에 맞는 솔루션을 게시하고 싶습니다. 어쩌면 누군가에게도 도움이 될 것입니다.

내 경우는 다음과 같습니다. 각 enum 키를 반복 한 다음 일부 키를 필터링 한 다음 enum에서 계산 된 값으로 키가있는 일부 객체에 액세스하려고합니다. 이것이 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]
    }))

3

열거 형 값으로 유형을 확인하는 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'
}

사용 방법:

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

NumberValueEnum 키의 결과 : [ "A", "B"]

NumberValueEnum 값에 대한 결과 : [0, 1]

StringValueEnumkeys의 결과 : [ "A", "B"]

StringValueEnum 값의 결과 : [ "A", "B"]


2

그 솔루션이 더 우아하다는 것을 알았습니다.

for (let val in myEnum ) {

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

다음이 표시됩니다.

bar 
foo

2

내 열거 형은 다음과 같습니다.

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

2

열거 형이 있다면

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

Argument of type '(d: Diet) => void' is not assignable to parameter of type '(value: string, index: number, array: string[]) => void'. Types of parameters 'd' and 'value' are incompatible. Type 'string' is not assignable to type 'MyEnum'.(2345)
jrheling

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
}

이 함수는 쉽게 열거 할 수 있고 열거 형으로 캐스팅 할 수있는 것을 반환합니다.


0

현재 버전의 TypeScript를 사용하면 이와 같은 기능을 사용하여 Enum을 선택한 레코드에 매핑 할 수 있습니다. 숫자 값이있는 키를 찾기 때문에 이러한 함수를 사용하여 문자열 값을 정의 할 수 없습니다.

enum STATES {
  LOGIN,
  LOGOUT,
}

export const enumToRecordWithKeys = <E extends any>(enumeration: E): E => (
  Object.keys(enumeration)
    .filter(key => typeof enumeration[key] === 'number')
    .reduce((record, key) => ({...record, [key]: key }), {}) as E
);

export const enumToRecordWithValues = <E extends any>(enumeration: E): E => (
  Object.keys(enumeration)
    .filter(key => typeof enumeration[key] === 'number')
    .reduce((record, key) => ({...record, [key]: enumeration[key] }), {}) as E
);

const states = enumToRecordWithKeys(STATES)
const statesWithIndex = enumToRecordWithValues(STATES)

console.log(JSON.stringify({
  STATES,
  states,
  statesWithIndex,
}, null ,2));

// Console output:
{
  "STATES": {
    "0": "LOGIN",
    "1": "LOGOUT",
    "LOGIN": 0,
    "LOGOUT": 1
  },
  "states": {
    "LOGIN": "LOGIN",
    "LOGOUT": "LOGOUT"
  },
  "statesWithIndex": {
    "LOGIN": 0,
    "LOGOUT": 1
  }
}

0

이미 많은 답변이 있지만 어쨌든 솔루션을 스택에 넣을 것이라고 생각합니다.

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

선명도 :

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

TypeScript 레코드에 대한 참조

좋은 도우미 기능 :

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

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

0

사용해야하는 열거 형 값 목록을 가져 오려면 다음을 수행하십시오.

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

Object.values(AnimalEnum);

-1

귀하의 질문에 대한 정확한 답변은 아니지만 문제를 해결하기위한 비결입니다.

export module Gender {

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

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

}

원하는 방식으로 목록 모델을 확장 할 수 있습니다.

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

이제 다음과 같이 사용할 수 있습니다.

for(const gender of Gender.List){
  console.log(gender.name);
  console.log(gender.value);
}

또는:

if(i === Gender.Type.Male){
  console.log("I am a man.");
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.