TypeScript에서 열거 형에 값이 있는지 확인하십시오.


163

나는 숫자를 받고이 type = 3열거 형에 존재하는지 확인해야합니다.

export const MESSAGE_TYPE = {
    INFO: 1,
    SUCCESS: 2,
    WARNING: 3,
    ERROR: 4,
};

내가 찾은 가장 좋은 방법은 모든 Enum Values를 배열로 가져 와서 indexOf를 사용하는 것입니다. 그러나 결과 코드는 읽기 쉽지 않습니다.

if( -1 < _.values( MESSAGE_TYPE ).indexOf( _.toInteger( type ) ) ) {
    // do stuff ...
}

이 작업을 수행하는 간단한 방법이 있습니까?


if(Object.values(MESSAGE_TYPE).includes(+type)? 할 수있는 일이 많지 않습니다.
— Andrew Li

1
ES6에서는 작동하지만 불행히도 ES5에서는 작동하지 않습니다.
— Tim Schoch

@TimSchoch !!MESSAGE_TYPE[type]값이 존재하는지 확인하기 만하면 됩니다. MESSAGE_TYPE[type]의 값이 type존재하지 않으면 undefined를 반환 합니다.MESSAGE_TYPE
— Kevin Babcock

1
@Kevin Babcock 열거 형 값 중 하나에 실패하면에 매핑됩니다 0.
— Ingo Bürk

@ Ingo Bürk 그레이트 포인트! 나는 명백한 점검을 할 수있을 것 같다MESSAGE_TYPE[type] !== undefined
— Kevin Babcock

답변:


213

이것을 문자열 열거 형과 함께 사용 Object.values(ENUM).includes(ENUM.value)하려면 https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-4.html 에 따라 문자열 열거 형이 역 매핑되지 않기 때문에 사용해야 합니다 .

Enum Vehicle {
    Car = 'car',
    Bike = 'bike',
    Truck = 'truck'
}

된다 :

{
    Car: 'car',
    Bike: 'bike',
    Truck: 'truck'
}

따라서 다음을 수행하면됩니다.

if (Object.values(Vehicle).includes('car')) {
    // Do stuff here
}

에 대한 오류가 발생 Property 'values' does not exist on type 'ObjectConstructor'하면 ES2017을 타겟팅하지 않은 것입니다. 이 tsconfig.json 구성을 사용할 수 있습니다.

"compilerOptions": {
    "lib": ["es2017"]
}

또는 당신은 그냥 캐스트를 할 수 있습니다 :

if ((<any>Object).values(Vehicle).includes('car')) {
    // Do stuff here
}

7
JSONLint가 표시 중 Property 'values' does not exist on type 'ObjectConstructor'입니다.
— BBaysinger

5
@BBaysinger에서 타이프 라이터 대신이 시도 :(<any>Object).values(Vehicle).includes(Vehicle.car)
— 살렘 Ouerdani

1
우수한. 이것이 정답입니다. 열거 형 키와 값이 다른 경우 허용되는 답변이 작동하지 않습니다.
— Pratap AK

2
타이프 스크립트에서는 작동하지 않습니다. 또한이 문제를 해결하려면 IE에서 휴식을 취하십시오
— Jerin Joseph

3
나는 이것이이 질문에 대한 답이 아니라고 믿는다. 해결책 (Object.values(Vehicle).includes(Vehicle.car))은 항상 사실이지만 문제는 주어진 값이 열거 형에 포함되어 있는지 확인하는 것입니다. 예를 들어 (Object.values(Vehicle).includes('car'))반환 해야 true하지만 (Object.values(Vehicle).includes('plane'))false를 반환해야합니다.
— tommybernaciak

140

TypeScript를 사용하는 경우 실제 enum을 사용할 수 있습니다 . 그런 다음를 사용하여 확인할 수 있습니다 in.

열거 형이 숫자 기반이며 표시되어 있지 않은 경우에만 작동합니다 const.

export enum MESSAGE_TYPE {
    INFO = 1,
    SUCCESS = 2,
    WARNING = 3,
    ERROR = 4,
};

var type = 3;

if (type in MESSAGE_TYPE) {

}

위 열거 형을 컴파일 할 때 아래 객체를 생성하기 때문에 작동합니다.

{
    '1': 'INFO',
    '2': 'SUCCESS',
    '3': 'WARNING',
    '4': 'ERROR',
    INFO: 1,
    SUCCESS: 2,
    WARNING: 3,
    ERROR: 4
}

이것은 적절한 열거 형에서만 작동합니다. 현재 다음과 같이 정의되어 있습니다.export const MESSAGE_TYPE = { ... }
— Tim Schoch

예. 적절한 열거 형 만 사용하십시오.
— 사라 바나

알겠습니다. 설명해 주셔서 감사합니다. 적절한 열거 형을 사용하지 않는 이유를 확인하고 변경할 수 있는지 확인하겠습니다.
— Tim Schoch

MESSAGE_TYPE제안한대로 실제 열거 형으로 변경 되었으며 이제 솔루션이 매력처럼 작동합니다. 감사합니다 @Saravana
— Tim Schoch

71
문자열 enum은 역 맵핑되지 않기 때문에 작동하지 않습니다 : typescriptlang.org/docs/handbook/release-notes/…
— Xiv

20

TypeScript v3.7.3

export enum YourEnum {
   enum1 = 'enum1',
   enum2 = 'enum2',
   enum3 = 'enum3',
}

const status = 'enumnumnum';

if (!(status in YourEnum)) {
     throw new UnprocessableEntityResponse('Invalid enum val');
}

3
나는 이것을 가장 좋아한다
— Ashley Coolman

3
그래서이 예제는 key == value를 사용하고 있는데 이것이 작동하는 이유입니다. key! = value이면 키로 확인합니다.
— 콘스탄틴 펠레 펠린

14
실제로이 경우는 우연의 일치로만 작동합니다. 'enum1'은 키와 동일한 값이므로 찾을 수 있습니다. 그러나 키가 값과 다르면 작동하지 않습니다.
— lukas_o

3
@lukas_o가 맞습니다. 이 솔루션은 언뜻보기에 분명해 보이지만 버그가 발생하기 쉽습니다.
— piotros

14

귀하의 질문에 대한 매우 간단하고 쉬운 해결책이 있습니다.

var districtId = 210;

if (DistrictsEnum[districtId] != null) {

// Returns 'undefined' if the districtId not exists in the DistrictsEnum 
    model.handlingDistrictId = districtId;
}

답변 해 주셔서 감사합니다. 프로그래밍에서 풀 타임 UX 디자인으로 옮겼으므로 더 이상 확인할 수 없습니다. @crowd, 2019 년에 여전히 받아 들일 수있는 대답인지 알려주세요! 건배
— 팀 Schoch

2
@ TimSchoch 적어도 숫자 열거 형에 대해 이것이 잘 작동한다는 것을 확인할 수 있습니다. 이것은 가장 우아한 솔루션 imho입니다.
— Patrick P.

@PatrickP. Ester가 제안한 솔루션이 문자열 열거 형에서도 작동하는지 확인할 수 있습니까?
— Tim Schoch

1
@TimSchoch 네! 문자열에서도 작동합니다. 사전처럼-사전의 키에 모든 유형을 사용할 수 있습니다.
— Ester Kaufman

9
열거 형이 열거 형 멤버 이름과 다른 값을 가진 문자열 이니셜 라이저를 사용하는 경우 문자열 열거 형에는 작동하지 않습니다. 아래 XIV의 답변을 @ 참조하십시오 stackoverflow.com/a/47755096/4752920
— kcstricks

5
export enum UserLevel {
  Staff = 0,
  Leader,
  Manager,
}

export enum Gender {
  None = "none",
  Male = "male",
  Female = "female",
}

로그의 차이 결과 :

log(Object.keys(Gender))
=>
[ 'None', 'Male', 'Female' ]

log(Object.keys(UserLevel))
=>
[ '0', '1', '2', 'Staff', 'Leader', 'Manager' ]

해결책은 키를 숫자로 제거해야합니다.

export class Util {
  static existValueInEnum(type: any, value: any): boolean {
    return Object.keys(type).filter(k => isNaN(Number(k))).filter(k => type[k] === value).length > 0;
  }
}

용법

// For string value
if (!Util.existValueInEnum(Gender, "XYZ")) {
  //todo
}

//For number value, remember cast to Number using Number(val)
if (!Util.existValueInEnum(UserLevel, 0)) {
  //todo
}

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