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.