TypeScript에서 문자열을 열거 형으로 변환하려면 어떻게합니까?


311

TypeScript에서 다음 열거 형을 정의했습니다.

enum Color{
    Red, Green
}

이제 내 기능에서 색상을 문자열로받습니다. 다음 코드를 시도했습니다.

var green= "Green";
var color : Color = <Color>green; // Error: can't convert string to enum

해당 값을 열거 형으로 변환하려면 어떻게해야합니까?

답변:


430

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.gitbook.io/typescript/type-system/enums


111
이 기능은 작동하지 않습니다 --noImplicitAny(VS 체크되지 않은 "암시 적 '모든'유형 허용"). 그것은 error TS7017: Index signature of object type implicitly has an 'any' type.나를 위해 이것을 작동 : var color: Color = (<any>Color)[green];(버전 1.4로 테스트)
Vojta

3
@Vojta가 말했다. VS 2012에서는 작동하지 않습니다. 이것은 작동했지만 var 색상 : Color = (<any> Color) [green];
파이살 Mq

3
여기에서도 작동하지 않습니다. 공식 문서는 다음을 확인하는 것 같습니다 : typescriptlang.org/docs/handbook/release-notes/…
Pieter De Bie

26
--noImplicitAny var color : Color = Color[green as keyof typeof Color];
Jonas

2
@ Naxos84 내 answear 참조 stackoverflow.com/a/56076148/294242
Jonas

122

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


4
그래서 우리는 typecast를 사용할 수 있습니다 :let s = "Green"; let typedColor = <keyof typeof Color> s;
SergeyT

네, 및 교체 let와 함께 const캐스팅없이 의지 작동합니다. 이를 명확히하기 위해 예제를 업데이트했습니다. 감사합니다 @ SergeyT
Victor

1
typedColorString = Color["Black"];error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'
Dominik가

2
한 줄 답변 :const color: Color = Color[colorString as keyof typeof Color];
cscan

38

입력 문자열이 Color 열거 형과 정확히 일치한다고 확신하는 경우 다음을 사용하십시오.

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>다음을 입력 타이프는 오류를 표시합니다 :

인덱스 표현식이 'number'유형이 아니기 때문에 요소에 내재적으로 'any'유형이 있습니다.

기본적으로 TypeScript Enum 유형은 숫자 인덱스와 함께 작동 let c = Color[0]하지만 문자열 인덱스와 는 작동 하지 않습니다 let c = Color["string"]. 이것은보다 일반적인 이슈 인 Object string index 에 대한 Microsoft 팀의 알려진 제한 사항 입니다.


<컬러 키 종류>로 캐스팅 할 수도 있습니다. 또한 "0"은 잘못된 입력이지만 정의되지 않은 값을 반환하지 않으므로 typeof mayBeColor === 'number'를 확인하십시오
Quentin 2

@ Quentin2 숫자 문자열은 어떻습니까? 즉 typeof '0'이어야한다string
패트릭 Michaelsen

36
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

이 예제는 --noImplicitAnyTypeScript에서 작동합니다.

출처 :
https://github.com/Microsoft/TypeScript/issues/13775#issuecomment-276381229 https://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types


이유를 모르겠지만이 솔루션은 const enum (Typescript 3.8.3 사용) 에서 작동하지 않습니다.
Robin-Hoodie

30

이 메모 는 원래 질문이 아니라 바카라의 답변 과 관련이 있습니다.

내 코드에서 컴파일러가 다음 코드를 사용하여 "문자열을 색상으로 변환 할 수 없음"과 거의 비슷한 오류를 발생시키는 이상한 문제가있었습니다.

var colorId = myOtherObject.colorId; // value "Green";
var color: Color = <Color>Color[colorId]; // TSC error here: Cannot convert string to Color.

컴파일러 유형 추론이 혼란스러워지고 colorIdID가 아닌 열거 형 값 이라고 생각했습니다 . 문제를 해결하려면 ID를 문자열로 캐스팅해야했습니다.

var colorId = <string>myOtherObject.colorId; // Force string value here
var color: Color = Color[colorId]; // Fixes lookup here.

문제의 원인을 잘 모르겠지만 다른 사람이 같은 문제를 겪을 경우를 대비하여이 메모를 남길 것입니다.


감사합니다! 이것은 꽤 어리석은 문제이며 문제가 무엇인지 파악하기 어렵습니다 .Typescript는 열거 형을 처리하는 더 좋은 방법을 생각해보아야 할 것입니다.
ChickenFeet

25

다음 코드를 사용하여 작업했습니다.

var green= "Green";
var color : Color= <Color>Color[green];

23

열거 형에 문자열 값을 제공하면 스트레이트 캐스트가 정상적으로 작동합니다.

enum Color {
  Green = "Green",
  Red = "Red"
}

const color = "Green";
const colorEnum = color as Color;

1
매우 간단합니다. 좋은!
Bernoulli IT

1
유효하지 않은 색상을 방지하지 않기 때문에 오해의 소지가 있습니다. const colorEnum = "Blue" as Color오류가 없으며 colorEnum괜찮습니다. 그러나 당신이 console.log그것에 있었다면, 당신은 "파란색"을 보게 될 것입니다. Artru의 대답은 있기 때문에 좋은 colorEnum것입니다 undefined그리고 당신은 그 구체적으로 확인할 수 있습니다 -.
M Falanga

20

타입 스크립트를 사용하는 경우 : 위의 많은 솔루션이 작동하지 않거나 지나치게 복잡 할 수 있습니다.

상황 : 문자열이 열거 형 값과 동일하지 않습니다 (케이싱이 다름)

enum Color {
  Green = "green",
  Red = "red"
}

그냥 사용하십시오 :

const color = "green" as Color

15

또한 동일한 컴파일러 오류가 발생했습니다. Sly_cardinal의 접근 방식이 약간 짧습니다.

var color: Color = Color[<string>colorId];

추가로 : 열거 형을 문자열로 직렬화하는 자바 스크립트 레이어로 채워진 타입 스크립트 열거 형이있는 경우 (예 : AngularJS를 통한 Asp 웹 API) myProp.color = Color[<string><any>myProp.color] Cheers
Victor

1
이것은 인정 된 답변이어야합니다.
Miroslav Popov

9

TypeScript 컴파일러가 변수 유형이 문자열임을 알고 있으면 다음과 같이 작동합니다.

let colorName : string = "Green";
let color : Color = Color[colorName];

그렇지 않으면 컴파일러 경고를 피하기 위해 명시 적으로 문자열로 변환해야합니다.

let colorName : any = "Green";
let color : Color = Color["" + colorName];

런타임시 두 솔루션이 모두 작동합니다.


3
<string>colorName대신 typecast 를 사용하지 "" + colorName않습니까?
SergeyT

7

이 질문에는 많은 정보가 혼합되어 있으므로 Nick의 TypeScript 모델에서 열거 형 사용 안내서의 TypeScript 2.x +에 대한 전체 구현을 다루 겠습니다 .

이 안내서는 다음을위한 것입니다. 클라이언트 측에서 Enum으로 편리하게 모델링 될 서버에서 알려진 문자열 세트를 수집하는 클라이언트 측 코드를 작성하는 사람들.

열거 형 정의

열거 형부터 시작하겠습니다. 다음과 같이 보일 것입니다 :

export enum IssueType {
  REPS = 'REPS',
  FETCH = 'FETCH',
  ACTION = 'ACTION',
  UNKNOWN = 'UNKNOWN',
}

여기서 주목해야 할 두 가지는 :

  1. 우리는 이것을 문자열로 열거 된 열거 형으로 명시 적으로 선언하고있어 관련이없는 다른 숫자가 아닌 문자열로 인스턴스화 할 수 있습니다.

  2. 서버 모델에 존재하거나 존재하지 않는 옵션을 추가했습니다 : UNKNOWN. undefined원하는 대로 처리 할 수 ​​있지만 처리 | undefined를 단순화하기 위해 가능한 한 유형 을 피하고 싶습니다 .

UNKNOWN사례 를 갖는 것에 대한 가장 좋은 점은 코드에서 실제로 알 수 있고 알 수없는 열거 형 경우의 스타일을 밝고 빨간색으로 깜박임으로써 무언가를 올바르게 처리하지 못한다는 것을 알 수 있습니다.

열거 형 구문 분석

이 열거 형을 다른 모델에 포함 시키거나 단독으로 사용할 수도 있지만 JSON 또는 XML (ha)의 문자열 형식의 열거 형을 강력한 형식의 대응 형으로 구문 분석해야합니다. 다른 모델에 포함 된 경우이 구문 분석기는 클래스 생성자에 있습니다.

parseIssueType(typeString: string): IssueType {
  const type = IssueType[typeString];
  if (type === undefined) {
    return IssueType.UNKNOWN;
  }

  return type;
}

열거 형이 올바르게 구문 분석되면 올바른 유형으로 끝납니다. 그렇지 않으면, undefined당신은 그것을 가로 챌 수 있고 당신의 UNKNOWN사건을 반환 할 수 있습니다 . undefined알 수없는 사례로 사용하는 것을 선호하는 경우 열거 형 구문 분석 시도 결과를 반환 할 수 있습니다.

거기에서 구문 분석 기능을 사용하고 새로 강력한 유형 변수를 사용하면됩니다.

const strongIssueType: IssueType = parseIssueType('ACTION');
// IssueType.ACTION
const wrongIssueType: IssueType = parseIssueType('UNEXPECTED');
// IssueType.UNKNOWN

6
불행히도 이것은 정확하지 않거나 최소한 일반화 할 수없는 것 같습니다. 키가 할당 된 문자열과 같기 때문에 작동합니다. 그러나 내 경우와 같이 다르면 작동하지 않습니다. 문서 의 말에서 : "문자열 열거 형 멤버는 전혀 역방향 매핑을 생성하지 않습니다." 코드는 다음과 같이 컴파일됩니다 IssueType["REPS"]="REPS". 당신이 당신의 열거 조금 다른 정의했다면, 말하자면, REPS="reps"이 얻을 것이 IssueType["REPS"]="reps"있는 것 ...
고적운

... IssueType.UNKNOWN열쇠 reps에 키가 없기 때문에 항상 돌아옵니다 . 문자열에 하이픈이 포함되어있어 키로 사용할 수 없기 때문에 여전히 나쁜 해결책을 찾지 못했습니다.
altocumulus

마지막으로 컴파일러가 이것이 문자열 열거 형이 아님을 설득 하여이 답변 에서 해결책을 찾았습니다 . 이 정보를 자신의 답변으로 편집하는 것이 좋습니다.
altocumulus

6

열거 형 값을 반복하는 방법을 알아야했습니다 (여러 열거 형의 많은 순열을 테스트하고있었습니다).

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/


이 답변은 정직합니다! 그것을 사랑하십시오. 특히 문자열에서 열거 형을 만드는 방법. 이렇게하면 열거 형이나 다른 경우를 테스트 할 때 많은 타이핑을 줄일 수 있습니다.
Florian Leitgeb

예, Jest와 함께 사용 each하여 모든 단일 열거 형 사례를 한 가지 방법으로 만 테스트합니다
mikeb

6

enum에서에서 얻을 수있는 답변을 찾고 string있었지만 내 경우에는 열거 형 값에 다른 문자열 값이 있습니다. OP에는 간단한 열거 형이 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반환됩니다.
  • 우리는 캐스트 enumObjany인해 타이프 3.0 이상 (현재 타이프 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");

3

열거 형

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

나와 같은 열거 형을 가진 사람은 열거 return enumType[property];형 항목이 다음과 같은 경우에 넣어야 합니다Skills = "anyvalue"
neustart47

@ neustart47 질문을 하시겠습니까?
Очир Дармаев

질문이 아닙니다. 방금 전과 같은 사건을 검색하는 사람을 위해 몇 가지 변경 사항을 언급했습니다. 당신의 대답은 맞습니다.
neustart47

2

수행 한 방식으로 생성 된 열거 형은 정방향 (name -> value)및 역방향 (value -> name)매핑을 모두 저장하는 객체로 컴파일됩니다 . 이 크롬 devtools 스크린 샷에서 볼 수 있듯이 :

여기에 이미지 설명을 입력하십시오

다음은 이중 매핑의 작동 방식과 서로 캐스트하는 방법에 대한 예입니다.

enum Color{
    Red, Green
}
// To Number
var greenNr: number = Color['Green'];
console.log(greenNr); // logs 1

// To String
var greenString: string = Color[Color['Green']];  // or Color[Color[1]
console.log(greenString); // logs Green

// In your example

// recieve as Color.green instead of the string green
var green: string = Color[Color.Green];  

// obtain the enum number value which corresponds to the Color.green property
var color: Color = (<any>Color)[green];  

console.log(color); // logs 1

1

이 시도

var color : Color = (모든 색상) [ "Green];

3.5.3 버전에서 잘 작동합니다.


0

네임 스페이스를 사용하여 열거 형의 기능을 확장하는 경우 다음과 같은 작업을 수행 할 수도 있습니다

    enum Color {
        Red, Green
    }

    export namespace Color {
      export function getInstance(color: string) : Color {
        if(color == 'Red') {
          return Color.Red;
        } else if (color == 'Green') {
          return Color.Green;
        }
      }
    }

이렇게 사용하세요

  Color.getInstance('Red');

0

다른 변형이 될 수 있습니다

const green= "Green";

const color : Color = Color[green] as Color;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.