TypeScriptのenumに値が存在するかどうかを確認します


163

私は番号を受け取り、type = 3それがこの列挙型に存在するかどうかを確認する必要があります:

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

私が見つけた最良の方法は、すべての列挙値を配列として取得し、それに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 '26

1
@Kevin Babcock 0ただし、列挙値の1つに失敗すると、にマップされます。
インゴビュルク2018

@インゴビュルク素晴らしいポイント!明示的なチェックが行われると思いますMESSAGE_TYPE[type] !== undefined
Kevin Babcock

回答:


211

これを文字列列挙型で機能させる場合は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 2018

5
typescriptです内@BBaysingerは、代わりにこれを試してください:(<any>Object).values(Vehicle).includes(Vehicle.car)
セーラムOuerdani

1
優れた。これは受け入れられる答えになるはずです。列挙型のキーと値が異なる場合、承認された回答が機能しません
Pratap AK

2
これはtypescriptでは機能しません。また、IEで中断が発生したための回避

3
これはこの質問に対する答えではないと思います。あなたの解決策(Object.values(Vehicle).includes(Vehicle.car))は常に真ですが、問題は、特定の値が列挙型に含まれていることをどのようにチェックするかです。たとえば、(Object.values(Vehicle).includes('car'))返す必要trueがあるが(Object.values(Vehicle).includes('plane'))偽を返す必要があります。
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 = { ... }
ティム・ショック

はい。適切な列挙型でのみ。
サラバナ2017

わかりました、説明してくれてありがとう。適切な列挙型を使用していない理由を確認し、それを変更できるかどうかを確認します。
Tim Schoch

MESSAGE_TYPEあなたが提案したように、私たちは実際の列挙型に変更し、今あなたのソリューションは魅力のように機能します。ありがとう@Saravana
Tim Schoch

71
文字列列挙は逆マッピングされないため、これは機能しません。typescriptlang.org
handbook

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
私はこれが一番好きです
アシュリークールマン

3
したがって、この例ではkey == valueを使用していますが、それが機能する理由ですよね?key!= valueの場合、キーでチェックされます。
Konstantin Pelepelin

13
実際、このケースは偶然のためにのみ機能します。'enum1'はキーと同じ値であるため、検出されるだけです。ただし、キーが値と異なる場合は機能しません。
lukas_o

3
@lukas_oはそれについて正しいです。このソリューションは一見すると見た目は明らかですが、間違いなくバグが発生しやすいものです。
ピオトロ

14

あなたの質問には非常にシンプルで簡単な解決策があります:

var districtId = 210;

if (DistrictsEnum[districtId] != null) {

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

エスターさん、ありがとうございます。プログラミングからフルタイムのUXデザインに移行したので、これを確認できなくなりました。@群衆、私が受け入れた答えがまだ2019年に行く方法であるかどうか私に知らせてください!乾杯
Tim Schoch

2
@TimSchoch私はこれが少なくとも数値列挙型で非常にうまく機能することを確認できます。これは最もエレガントなソリューションimhoです。
Patrick P.

@PatrickP。Esterによって提案されたソリューションが文字列列挙型でも機能することを確認できますか?
Tim Schoch

1
@TimSchochはい!文字列でも機能します。辞書のように-辞書のキーには任意のタイプを使用できます。
Ester Kaufman

9
enumがenumメンバー名とは異なる値を持つ文字列初期化子を使用する場合、これは文字列enumには機能しないことに注意してください。:以下エクシブの答え@を参照してください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.