103 votes

Comment comparer les énumérations dans TypeScript

À la Machine, je veux comparer deux variables contenant les valeurs de l'enum. Voici mon code minimal exemple:

enum E {
  A,
  B
}

let e1: E = E.A
let e2: E = E.B

if (e1 === e2) {
  console.log("equal")
}

Lors de la compilation avec tsc (v 2.0.3), je reçois le message d'erreur suivant:

TS2365: l'Opérateur '===' ne peut pas être appliquée aux types "E. A" et "E. B".

Même avec ==, !== et !=. J'ai essayé d'ajouter l' const mot clé, mais qui ne semble pas avoir d'effet. Le Tapuscrit spec dit ce qui suit:

4.19.3 L'<, >, <=, >=, ==, !=, ===, et !== les opérateurs

Ces exploitants ont besoin de l'un ou des deux opérandes de types à être cédés à l'autre. Le résultat est toujours le Booléen de type primitif.

Qui (je pense) explique l'erreur. Mais comment puis-je obtenir autour d'elle?

Note de côté
Je suis l'aide de l'Atome de l'éditeur avec l'atome-tapuscrit, et je ne reçois pas toutes les erreurs/avertissements dans mon éditeur. Mais lorsque j'exécute tsc dans le même répertoire que je reçois le message d'erreur ci-dessus. Je pensais qu'ils étaient censés utiliser le même tsconfig.json le fichier, mais apparemment ce n'est pas le cas.

63voto

John J. Camilleri Points 589

Eh bien, je pense avoir trouvé quelque chose qui fonctionne:

 if (e1.valueOf() === e2.valueOf()) {
  console.log("equal")
}
 

Mais je suis un peu surpris que cela ne soit mentionné nulle part dans la documentation.

31voto

artem Points 269

Il est une autre façon: si vous ne voulez pas généré de code javascript à être affecté, vous pouvez utiliser le type de distribution:

let e1: E = E.A
let e2: E = E.B


if (e1 as E === e2 as E) {
  console.log("equal")
}

En général, cela est causé par le contrôle de flux basé sur l'inférence de type. Avec l'actuel tapuscrit de mise en œuvre, il est éteinte lorsque la fonction d'appel est en cause, vous pouvez également faire ceci:

let id = a => a

let e1: E = id(E.A)
let e2: E = id(E.B)

if (e1 === e2) {
  console.log('equal');
}

La chose étrange est, il n'y a pas encore de message d'erreur si l' id fonction est déclarée pour revenir précisément le même type que son agument:

function id<T>(t: T): T { return t; }

13voto

Bellash Points 1330

Si était capable de comparer deux enums avec cette

  if (product.ProductType && 
       (product.ProductType.toString() == ProductTypes[ProductTypes.Merchandises])) {
      // yes this item is of merchandises
  } 
 

avec ProductTypes étant ceci export enum ProductTypes{Merchandises,Goods,...}

13voto

Lu15 Points 136

Dans mon cas, aucune des deux solutions n'a fonctionné, la raison était que j'étais un moulage de la valeur d'enum enum objet.

Après que j'essayais de savoir si l'enum est équivalent à un autre enum objet... donc j'ai créé le générique de fonctions:

  public static enumEquals<T>(e: any, e1: T, e2: T): boolean {
    const v1 = this.enumValue(e, e1);
    return v1 === this.enumValue(e, e2, typeof v1);
  }

  private static enumValue<T>(enumType: any, value: T, validType?: string) {
    let v = enumType[value];
    if (!validType) {
      return v;
    }
    while (typeof v !== validType) {
      v = enumType[v];
    }
    return v;
  }

Ceci est un exemple de mon cas de test:

enum SomeEnum {
  VALUE1, VALUE2, VALUE3, VALUE_DEF
}

const enumRefKey = localStorage.getItem('someKey');
const parsedEnum = SomeEnum[enumRefKey] || SomeEnum.VALUE_DEF;
console.log(parsedEnum);
if (parsedEnum === SomeEnum.VALUE_DEF) {
  // do stuff
}

Évidemment, ce code n'a pas fonctionné, après j'ai essayé les solutions données ici à ces questions, j'ai constaté que lorsque enumRefKey est valable console.log(parsedEnum) l'impression de nombres et le texte VALUE_DEF quand ne l'est pas. Le même résultat se réalise à l'aide de toutes les autres solutions:

  • parsedEnum comme SomeEnum
  • parsedEnum.valueOf()
  • SomeEnum[parsedEnum]

La solution en utilisant les méthodes génériques ressemble à ceci:

enum SomeEnum {
  VALUE1, VALUE2, VALUE3, VALUE_DEF
}

const enumRefKey = localStorage.getItem('someKey');
const parsedEnum = SomeEnum[enumRefKey] || SomeEnum.VALUE_DEF;
console.log(parsedEnum);
if (this.enumEquals(SomeEnum, parsedEnum, SomeEnum.VALUE_DEF) {
  // do stuff
}

J'espère que cela aide quelqu'un.

8voto

Russ Points 191

La seule chose qui a fonctionné pour moi (en caractères d'imprimerie 2.2.1) est-ce que:

if (E[e1] === E[e2]) {
  console.log("equal")
}

Ce compare les chaînes de caractères représentant le nom (par exemple. "A" et "B").

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