web-dev-qa-db-fra.com

Comment obtient-on les noms des entrées TypeScript enum?

J'aimerais savoir comment itérer une énumération TypeScript et chaque nom de symbole énuméré.

Par exemple.,

enum myEnum { entry1, entry2 }

for (var entry in myEnum) { 
    // use entry's name here, e.g., "entry1"
}
180
CalvinDale

Le code que vous avez posté fonctionnera; il affichera tous les membres de l'énum, ​​y compris les valeurs des membres de l'énum. Par exemple, le code suivant:

enum myEnum { bar, foo }

for (var enumMember in myEnum) {
   console.log("enum member: ", enumMember);
}

Imprimera ce qui suit:

Enum member: 0
Enum member: 1
Enum member: bar
Enum member: foo

Si vous voulez plutôt que les noms des membres, et non les valeurs, vous pouvez faire quelque chose comme ceci:

for (var enumMember in myEnum) {
   var isValueProperty = parseInt(enumMember, 10) >= 0
   if (isValueProperty) {
      console.log("enum member: ", myEnum[enumMember]);
   }
}

Cela n'imprimera que les noms:

Membre de l'énumération: bar 

Enum membre: foo

Avertissement: cela repose légèrement sur un détail d'implémentation: TypeScript compile des énumérations en un objet JS, les valeurs enum étant membres de l'objet. Si TS décidait de les mettre en œuvre de manière différente à l’avenir, la technique ci-dessus pourrait casser.

153

Bien que la réponse soit déjà fournie, presque personne n’a pointé la docs

Voici un extrait

enum Enum {
    A
}
let nameOfA = Enum[Enum.A]; // "A"
166
shakram02

En supposant que vous respectiez les règles et ne produisez que des énumérations avec des valeurs numériques, vous pouvez utiliser ce code. Cela gère correctement le cas où vous avez un nom qui est un nombre valide comme par hasard 

enum Color {
    Red,
    Green,
    Blue,
    "10" // wat
}

var names: string[] = [];
for(var n in Color) {
    if(typeof Color[n] === 'number') names.Push(n);
}
console.log(names); // ['Red', 'Green', 'Blue', '10']
49
Ryan Cavanaugh

Pour moi, un moyen plus facile, pratique et direct de comprendre ce qui se passe est le recensement suivant:

enum colors { red, green, blue };

Sera converti essentiellement à ceci:

var colors = { red: 0, green: 1, blue: 2,
               [0]: "red", [1]: "green", [2]: "blue" }

Pour cette raison, ce qui suit sera vrai:

colors.red === 0
colors[colors.red] === "red"
colors["red"] === 0

Cela crée un moyen facile d’obtenir le nom d’un dénombré comme suit:

var color: colors = colors.red;
console.log("The color selected is " + colors[color]);

Cela crée également un moyen agréable de convertir une chaîne en une valeur énumérée.

var colorName: string = "green";
var color: colors = colors.red;
if (colorName in colors) color = colors[colorName];

Les deux situations ci-dessus sont bien plus courantes, car vous êtes généralement plus intéressé par le nom d'une valeur spécifique et par la sérialisation des valeurs de manière générique.

37
Michael Erickson

Si vous ne recherchez que les noms et parcourez-les ultérieurement, utilisez:

Object.keys(myEnum).map(key => myEnum[key]).filter(value => typeof value === 'string') as string[];
25
Simon

Avec la version actuelle 1.8.9 de TypeScript, j'utilise des énumérations typées:

export enum Option {
    OPTION1 = <any>'this is option 1',
    OPTION2 = <any>'this is option 2'
}

avec des résultats dans cet objet Javascript:

Option = {
    "OPTION1": "this is option 1",
    "OPTION2": "this is option 2",
    "this is option 1": "OPTION1",
    "this is option 2": "OPTION2"
}

je dois donc interroger des clés et des valeurs et ne renvoyer que des valeurs:

let optionNames: Array<any> = [];    
for (let enumValue in Option) {
    let optionNameLength = optionNames.length;

    if (optionNameLength === 0) {
        this.optionNames.Push([enumValue, Option[enumValue]]);
    } else {
        if (this.optionNames[optionNameLength - 1][1] !== enumValue) {
            this.optionNames.Push([enumValue, Option[enumValue]]);
        }
    }
}

Et je reçois les clés d’option dans un tableau:

optionNames = [ "OPTION1", "OPTION2" ];
19
Philip Miglinci

Cette solution fonctionne aussi.

enum ScreenType {
    Edit = 1,
    New = 2,
    View = 4
}

var type: ScreenType = ScreenType.Edit;

console.log(ScreenType[type]); //Edit
10
Carlinhos

Vous pouvez utiliser le paquetage enum-values que j'ai écrit quand j'ai eu le même problème:

Git: enum-values ​​

var names = EnumValues.getNames(myEnum);
10
Slava Shpitalny

A partir de TypeScript 2.4, les énumérations peuvent contenir string intializers https://www.typescriptlang.org/docs/handbook/release-notes/TypeScript-2-4.html

Cela vous permet d'écrire:

 enum Order {
      ONE = "First",
      TWO = "Second"
 }

console.log(`One is ${Order.ONE.toString()}`);

et obtenez cette sortie:

On est le premier

8
John Huebner

Sur la base de certaines réponses ci-dessus, je suis arrivé à cette signature de fonction sécurisée:

export function getStringValuesFromEnum<T>(myEnum: T): keyof T {
  return Object.keys(myEnum).filter(k => typeof (myEnum as any)[k] === 'number') as any;
}

Usage:

enum myEnum { entry1, entry2 };
const stringVals = getStringValuesFromEnum(myEnum);

le type de stringVals est 'entry1' | 'entry2'

Voir en action

6
Dmitry

À partir de TypeScript 2.4, l'énumération ne contiendrait plus la clé en tant que membre. source du type lisezmoi

La mise en garde est que les enums initialisés par chaîne ne peuvent pas être inversés pour obtenir le nom du membre enum original. En d'autres termes, vous ne pouvez pas écrire Colors ["RED"] pour obtenir la chaîne "Red".

Ma solution:

export const getColourKey = (value: string ) => {
    let colourKey = '';
    for (const key in ColourEnum) {
        if (value === ColourEnum[key]) {
            colourKey = key;
            break;
        }
    }
    return colourKey;
};
5
kitko112

Laissez ts-enum-util ( github , npm ) faire le travail pour vous et fournissez un grand nombre d’utilitaires compatibles avec le type. Fonctionne avec les enums string et numeric, en ignorant correctement les entrées de recherche inversée d'index numérique pour les enums numériques:

Enum String:

import {$enum} from "ts-enum-util";

enum Option {
    OPTION1 = 'this is option 1',
    OPTION2 = 'this is option 2'
}

// type: ("OPTION1" | "OPTION2")[]
// value: ["OPTION1", "OPTION2"]
const keys= $enum(Option).getKeys();

// type: Option[]
// value: ["this is option 1", "this is option 2"]
const values = $enum(Option).getValues();

Énumérique:

enum Option {
    OPTION1,
    OPTION2
}

// type: ("OPTION1" | "OPTION2")[]
// value: ["OPTION1", "OPTION2"]
const keys= $enum(Option).getKeys();

// type: Option[]
// value: [0, 1]
const values = $enum(Option).getValues();
5
Jeff Lau

Une autre solution intéressante fondée ici utilise ES6 Map:

export enum Type {
  low,
  mid,
  high
}

export const TypeLabel = new Map<number, string>([
  [Type.low, 'Low Season'],
  [Type.mid, 'Mid Season'],
  [Type.high, 'High Season']
]);

UTILISATION

console.log(TypeLabel.get(Type.low)); // Low Season
5
manzapanza

Selon la documentation TypeScript, nous pouvons le faire via Enum avec des fonctions statiques.

Obtenir le nom Enum avec des fonctions statiques 

enum myEnum { 
    entry1, 
    entry2 
}

namespace myEnum {
    export function GetmyEnumName(m: myEnum) {
      return myEnum[m];
    }
}


now we can call it like below
myEnum.GetmyEnumName(myEnum.entry1);
// result entry1 

pour en savoir plus sur Enum avec une fonction statique, suivez le lien ci-dessous https://basarat.gitbooks.io/TypeScript/docs/enums.html

2
Shahid Ahmad

La meilleure façon, à mon avis, est de simplement déclarer les valeurs enum souhaitées. De cette façon, leur accès est propre et joli (à chaque fois).

enum myEnum { entry1 = 'VALUE1', entry2 = 'VALUE2' }

for (var entry in myEnum) { 
    console.log(entry);
}

produira:

VALUE1
VALUE2
2
stemadsen

Je trouve cette solution plus élégante:

for (let val in myEnum ) {

 if ( isNaN( parseInt( val )) )
     console.log( val );
}

Il affiche:

bar 
foo
1

J'ai écrit une classe EnumUtil qui effectue une vérification de type par la valeur enum:

export class EnumUtils {
  /**
   * Returns the enum keys
   * @param enumObj enum object
   */
  static getEnumKeys(enumObj: any, valueType: string): any[] {
    return EnumUtils.getEnumValues(enumObj, valueType).map(value => enumObj[value]);
  }

  /**
   * Returns the enum values
   * @param enumObj enum object
   */
  static getEnumValues(enumObj: any, valueType: string): any[] {
    return Object.keys(enumObj).filter(key => typeof enumObj[key] === valueType);
  }
}

Comment l'utiliser:

enum TestEnum{
  A= 0,
  B= 1
}

EnumUtils.getEnumKeys(TestEnum, "number");
EnumUtils.getEnumValues(TestEnum, "number");

Résultat pour les clés: ["A", "B"]

Résultat pour les valeurs: [0, 1]

1
Arnold Vakaria

La seule solution qui fonctionne pour moi dans tous les cas (même si les valeurs sont des chaînes) est la suivante:

var enumToString = function(enumType, enumValue) {
    for (var enumMember in enumType) {
        if (enumType[enumMember]==enumValue) return enumMember
    }
}
0
user2080105

J'ai trouvé cette question en cherchant "TypeScript iterate over enum keys". Donc, je veux juste poster une solution qui fonctionne pour moi dans mon cas. Cela aidera peut-être aussi quelqu'un.

Mon cas est le suivant: je veux parcourir chaque clé enum, puis filtrer certaines clés, puis accéder à un objet contenant des clés en tant que valeurs calculées à partir de enum. Donc, voici comment je le fais sans aucune erreur TS.

    enum MyEnum = { ONE = 'ONE', TWO = 'TWO' }
    const LABELS = {
       [MyEnum.ONE]: 'Label one',
       [MyEnum.TWO]: 'Label two'
    }


    // to declare type is important - otherwise TS complains on LABELS[type]
    // also, if replace Object.values with Object.keys - 
    // - TS blames wrong types here: "string[] is not assignable to MyEnum[]"
    const allKeys: Array<MyEnum> = Object.values(MyEnum)

    const allowedKeys = allKeys.filter(
      (type) => type !== InsuranceType.OSAGO
    )

    const allowedLabels = allowedKeys.map((type) => ({
      label: LABELS[type]
    }))
0
Alendorff

Mon Enum est comme ça:

export enum UserSorting {
    SortByFullName = "Sort by FullName", 
    SortByLastname = "Sort by Lastame", 
    SortByEmail = "Sort by Email", 
    SortByRoleName = "Sort by Role", 
    SortByCreatedAt = "Sort by Creation date", 
    SortByCreatedBy = "Sort by Author", 
    SortByUpdatedAt = "Sort by Edit date", 
    SortByUpdatedBy = "Sort by Editor", 
}

faisant ainsi ce retour undefined :

UserSorting[UserSorting.SortByUpdatedAt]

Pour résoudre ce problème, j'ai choisi un autre moyen de le faire à l'aide d'un tuyau:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
    name: 'enumKey'
})
export class EnumKeyPipe implements PipeTransform {

  transform(value, args: string[] = null): any {
    let enumValue = args[0];
    var keys = Object.keys(value);
    var values = Object.values(value);
    for (var i = 0; i < keys.length; i++) {
      if (values[i] == enumValue) {
        return keys[i];
      }
    }
    return null;
    }
}

Et pour l'utiliser:

return this.enumKeyPipe.transform(UserSorting, [UserSorting.SortByUpdatedAt]);
0
Cedric Arnould