400 votes

Vérifier si une valeur existe dans un enum en TypeScript

Je reçois un numéro type = 3 et il faut vérifier s'il existe dans cet enum :

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

Le meilleur moyen que j'ai trouvé est de récupérer toutes les valeurs des Enum dans un tableau et d'utiliser indexOf dessus. Mais le code résultant n'est pas très lisible :

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

Existe-t-il un moyen plus simple de procéder ?

0 votes

if(Object.values(MESSAGE_TYPE).includes(+type) ? Il n'y a pas grand-chose que vous puissiez faire.

1 votes

Cela fonctionne dans ES6 mais pas dans ES5 malheureusement.

0 votes

@TimSchoch Vous pouvez juste faire !!MESSAGE_TYPE[type] pour vérifier si une valeur existe. MESSAGE_TYPE[type] retournera undefined si la valeur de type n'existe pas sur MESSAGE_TYPE

503voto

Xiv Points 1609

Si vous voulez que cela fonctionne avec les enums de type chaîne, vous devez utiliser Object.values(ENUM).includes(ENUM.value) parce que les enums de chaîne ne sont pas inversés, conformément à la directive https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-4.html :

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

devient :

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

Donc tu dois juste faire :

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

Si vous obtenez une erreur pour : Property 'values' does not exist on type 'ObjectConstructor' alors vous ne ciblez pas l'ES2017. Vous pouvez soit utiliser cette configuration tsconfig.json :

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

Ou tu peux juste faire un casting quelconque :

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

14 votes

JSONLint montre Property 'values' does not exist on type 'ObjectConstructor' .

5 votes

@BBaysinger en tapuscrit, essayez ceci à la place : (<any>Object).values(Vehicle).includes(Vehicle.car)

1 votes

Excellent. Cela devrait être la réponse acceptée. La réponse acceptée ne fonctionnera pas si les clés et les valeurs de mon enum sont différentes.

257voto

Saravana Points 14313

Cela ne fonctionne que sur les enums non-const, basés sur des nombres. Pour les enums const ou les enums d'autres types, voir cette réponse ci-dessus


Si vous utilisez TypeScript, vous pouvez utiliser une balise enum réel . Vous pouvez ensuite le vérifier en utilisant in .

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

var type = 3;

if (type in MESSAGE_TYPE) {

}

Cela fonctionne car lorsque vous compilez l'enum ci-dessus, cela génère l'objet ci-dessous :

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

0 votes

Cela ne fonctionne qu'avec des enums appropriés, n'est-ce pas ? actuellement, il est défini comme tel : export const MESSAGE_TYPE = { ... }

1 votes

Oui. Seulement avec des enums appropriés.

0 votes

Ok, merci pour l'explication. Je vais vérifier pourquoi nous n'utilisons pas un enum correct et voir si nous pouvons le changer.

88voto

SoonDead Points 3009

D'après Sandersn le meilleur moyen de le faire serait :

Object.values(MESSAGE_TYPE).includes(type as MESSAGE_TYPE)

3 votes

C'est probablement la meilleure et la plus sûre des réponses. Elle évite l'utilisation de any . Le site type in MESSAGE_TYPE La syntaxe pourrait être meilleure si vous pouvez garantir que la clé et la valeur de l'enum seront les mêmes puisqu'il s'agit d'une recherche par clé plutôt que par valeur.

2 votes

Aha ! trouvé plus bas dans les réponses, je peux confirmer que cette solution fonctionne sans aucune any ou le type se plaint, ET cela fonctionne lorsque les noms d'enum eux-mêmes ne correspondent pas à leurs valeurs réelles respectives (comme beaucoup de solutions bricolées sur cette page le suggèrent ou l'utilisent). Ce devrait être la réponse acceptée, surtout si elle provient du GitHub de TypeScript.

2 votes

Cela fonctionne pour tous les cas que vous devez vérifier. Réponse parfaite.

39voto

Jayson S.A. Points 351
export enum YourEnum {
   enum1 = 'enum1',
   enum2 = 'enum2',
   enum3 = 'enum3',
}

const status = 'enumnumnum';

if (!Object.values(YourEnum).includes(status)) {
     throw new UnprocessableEntityResponse('Invalid enum val');
}

3 votes

C'est ce que j'aime le plus

3 votes

Donc cet exemple utilise juste key==value et c'est la raison pour laquelle ça marche, non ? Si key!=value, la vérification se ferait par key.

45 votes

En fait, ce cas ne fonctionne qu'en raison d'une coïncidence. 'enum1' ne serait trouvé que parce que c'est la même valeur que la clé. Mais si les clés diffèrent des valeurs, cela ne fonctionne pas.

18voto

Ester Or Points 380

Il existe une solution très simple et facile à votre question :

var districtId = 210;

if (DistrictsEnum[districtId] != null) {

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

0 votes

Merci Ester pour votre réponse. Depuis que je suis passé de la programmation au design UX à plein temps, je ne peux plus vérifier. @crowd, faites-moi savoir si je la réponse acceptée est toujours la voie à suivre en 2019 ! Salutations

2 votes

@TimSchoch Je peux confirmer que cela fonctionne très bien, du moins pour les enums numériques. C'est la solution la plus élégante à mon avis.

0 votes

@PatrickP. pouvez-vous confirmer que la solution proposée par Ester fonctionne également pour les enums de type chaîne ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X