Ich möchte ein TypeScript und einen enum
Typ iterieren und jeden aufgezählten Symbolnamen erhalten, z.
enum myEnum { entry1, entry2 }
for (var entry in myEnum) {
// use entry's name here, e.g., "entry1"
}
Ich möchte ein TypeScript und einen enum
Typ iterieren und jeden aufgezählten Symbolnamen erhalten, z.
enum myEnum { entry1, entry2 }
for (var entry in myEnum) {
// use entry's name here, e.g., "entry1"
}
Antworten:
Der von Ihnen veröffentlichte Code funktioniert. Es werden alle Mitglieder der Aufzählung ausgedruckt, einschließlich der Werte der Aufzählungsmitglieder. Zum Beispiel der folgende Code:
enum myEnum { bar, foo }
for (var enumMember in myEnum) {
console.log("enum member: ", enumMember);
}
Druckt Folgendes:
Enum member: 0
Enum member: 1
Enum member: bar
Enum member: foo
Wenn Sie stattdessen nur die Mitgliedsnamen und nicht die Werte möchten, können Sie Folgendes tun:
for (var enumMember in myEnum) {
var isValueProperty = parseInt(enumMember, 10) >= 0
if (isValueProperty) {
console.log("enum member: ", myEnum[enumMember]);
}
}
Das druckt nur die Namen aus:
Enum-Mitglied: Bar
Enum-Mitglied: foo
Vorsichtsmaßnahme: Dies hängt geringfügig von einem Implementierungsdetail ab: TypeScript kompiliert Aufzählungen zu einem JS-Objekt, wobei die Aufzählungswerte Mitglieder des Objekts sind. Wenn TS beschließt, sie in Zukunft anders zu implementieren, könnte die oben genannte Technik brechen.
+enumMember >= 0
sollte daran liegen, isFinite(+enumMember)
dass negative oder Gleitkommawerte auch umgekehrt abgebildet werden. ( Spielplatz )
Obwohl die Antwort bereits gegeben ist, zeigte fast niemand auf die Dokumente
Hier ist ein Ausschnitt
enum Enum {
A
}
let nameOfA = Enum[Enum.A]; // "A"
Beachten Sie, dass String-Enum-Mitglieder überhaupt keine umgekehrte Zuordnung erhalten.
0
oder 1
aus dieser Aufzählung? export enum Octave { ZERO = 0, ONE = 1 }
enum Enum {"A"}; let nameOfA = Enum[Enum.A];
? Ab
Angenommen, Sie halten sich an die Regeln und erstellen nur Aufzählungen mit numerischen Werten. Sie können diesen Code verwenden. Dies behandelt den Fall korrekt, in dem Sie einen Namen haben, der zufällig eine gültige Nummer ist
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']
Für mich ist die folgende Aufzählung eine einfachere, praktischere und direktere Möglichkeit zu verstehen, was vor sich geht:
enum colors { red, green, blue };
Wird im Wesentlichen darauf umgestellt:
var colors = { red: 0, green: 1, blue: 2,
[0]: "red", [1]: "green", [2]: "blue" }
Aus diesem Grund gilt Folgendes:
colors.red === 0
colors[colors.red] === "red"
colors["red"] === 0
Dies schafft eine einfache Möglichkeit, den Namen einer Aufzählung wie folgt zu erhalten:
var color: colors = colors.red;
console.log("The color selected is " + colors[color]);
Es bietet auch eine gute Möglichkeit, eine Zeichenfolge in einen Aufzählungswert zu konvertieren.
var colorName: string = "green";
var color: colors = colors.red;
if (colorName in colors) color = colors[colorName];
Die beiden oben genannten Situationen sind weitaus häufiger, da Sie normalerweise viel mehr am Namen eines bestimmten Werts und an der generischen Serialisierung von Werten interessiert sind.
Wenn Sie nur nach den Namen suchen und später wiederholen, verwenden Sie:
Object.keys(myEnum).map(key => myEnum[key]).filter(value => typeof value === 'string') as string[];
Object.values(myEnum).filter(value => typeof value === 'string') as string[];
Object.values(myEnum).filter(value => typeof value === 'string').map(key => { return {id: myEnum[key], type: key }; });
Mit der aktuellen TypeScript Version 1.8.9 verwende ich typisierte Enums:
export enum Option {
OPTION1 = <any>'this is option 1',
OPTION2 = <any>'this is option 2'
}
mit Ergebnissen in diesem Javascript-Objekt:
Option = {
"OPTION1": "this is option 1",
"OPTION2": "this is option 2",
"this is option 1": "OPTION1",
"this is option 2": "OPTION2"
}
Ich muss also Schlüssel und Werte abfragen und nur Werte zurückgeben:
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]]);
}
}
}
Und ich erhalte die Optionsschlüssel in einem Array:
optionNames = [ "OPTION1", "OPTION2" ];
Ab TypeScript 2.4 können Aufzählungen String-Intializer https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-4.html enthalten
So können Sie schreiben:
enum Order {
ONE = "First",
TWO = "Second"
}
console.log(`One is ${Order.ONE.toString()}`);
und erhalten Sie diese Ausgabe:
Einer ist der Erste
Eine weitere interessante Lösung hier verwendet ES6 Karte:
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']
]);
VERWENDEN
console.log(TypeLabel.get(Type.low)); // Low Season
Lassen Sie ts-enum-util
( github , npm ) die Arbeit für Sie erledigen und stellen Sie viele zusätzliche typsichere Dienstprogramme bereit. Funktioniert sowohl mit Zeichenfolgen als auch mit numerischen Aufzählungen und ignoriert die numerischen Index-Reverse-Lookup-Einträge für numerische Aufzählungen ordnungsgemäß:
String enum:
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();
Numerische Aufzählung:
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();
Ab TypeScript 2.4 würde die Aufzählung den Schlüssel als Mitglied nicht mehr enthalten. Quelle aus der TypeScript-Readme-Datei
Die Einschränkung besteht darin, dass durch Zeichenfolgen initialisierte Aufzählungen nicht rückwärts zugeordnet werden können, um den ursprünglichen Namen des Aufzählungsmitglieds zu erhalten. Mit anderen Worten, Sie können keine Farben ["ROT"] schreiben, um die Zeichenfolge "Rot" zu erhalten.
Meine Lösung:
export const getColourKey = (value: string ) => {
let colourKey = '';
for (const key in ColourEnum) {
if (value === ColourEnum[key]) {
colourKey = key;
break;
}
}
return colourKey;
};
Sie können das enum-values
Paket verwenden, das ich geschrieben habe, als ich das gleiche Problem hatte:
var names = EnumValues.getNames(myEnum);
Basierend auf einigen Antworten oben habe ich diese typsichere Funktionssignatur gefunden:
export function getStringValuesFromEnum<T>(myEnum: T): keyof T {
return Object.keys(myEnum).filter(k => typeof (myEnum as any)[k] === 'number') as any;
}
Verwendungszweck:
enum myEnum { entry1, entry2 };
const stringVals = getStringValuesFromEnum(myEnum);
die Art von stringVals
ist'entry1' | 'entry2'
(keyof T)[]
statt keyof T
. Außerdem verhindert dies, dass export
Ihr Spielplatz funktioniert.
Es scheint, dass keine der Antworten hier mit String-Enums im -mode funktioniert strict
.
Betrachten Sie die Aufzählung als:
enum AnimalEnum {
dog = "dog", cat = "cat", mouse = "mouse"
}
Der Zugriff mit AnimalEnum["dog"]
kann zu einem Fehler führen wie:
Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof AnimalEnum'.ts(7053)
.
Richtige Lösung für diesen Fall, schreiben Sie es als:
AnimalEnum["dog" as keyof typeof AnimalEnum]
keyof
mit typeof
! Eine andere Lösung scheint ziemlich undurchsichtig zu sein, aber ich denke, Typescript muss DX - Developer Experience für Enum
Ich denke, der beste Weg ist, einfach die gewünschten Aufzählungswerte zu deklarieren. Auf diese Weise ist der Zugriff auf sie sauber und hübsch (jedes Mal).
enum myEnum { entry1 = 'VALUE1', entry2 = 'VALUE2' }
for (var entry in myEnum) {
console.log(entry);
}
wird herstellen:
VALUE1
VALUE2
Laut TypeScript-Dokumentation können wir dies über Enum mit statischen Funktionen tun.
Holen Sie sich Enum Name mit statischen Funktionen
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
Weitere Informationen zu Enum mit statischer Funktion finden Sie unter folgendem Link: https://basarat.gitbooks.io/typescript/docs/enums.html
Die einzige Lösung, die in allen Fällen für mich funktioniert (auch wenn Werte Zeichenfolgen sind), ist die folgende:
var enumToString = function(enumType, enumValue) {
for (var enumMember in enumType) {
if (enumType[enumMember]==enumValue) return enumMember
}
}
Alte Frage, aber warum keine const
Objektkarte verwenden?
Anstatt dies zu tun:
enum Foo {
BAR = 60,
EVERYTHING_IS_TERRIBLE = 80
}
console.log(Object.keys(Foo))
// -> ["60", "80", "BAR", "EVERYTHING_IS_TERRIBLE"]
console.log(Object.values(Foo))
// -> ["BAR", "EVERYTHING_IS_TERRIBLE", 60, 80]
Tun Sie dies (achten Sie auf die as const
Besetzung):
const Foo = {
BAR: 60,
EVERYTHING_IS_TERRIBLE: 80
} as const
console.log(Object.keys(Foo))
// -> ["BAR", "EVERYTHING_IS_TERRIBLE"]
console.log(Object.values(Foo))
// -> [60, 80]
console.log(Object.keys(Foo))
im ersten Beispiel nur zurückkommt ["BAR", "EVERYTHING_IS_TERRIBLE"]
..
["60", "80", "BAR", "EVERYTHING_IS_TERRIBLE"]
Ich habe diese Frage gefunden, indem ich nach "TypeScript iteriere über Enum-Schlüssel" gesucht habe. Ich möchte also nur eine Lösung veröffentlichen, die in meinem Fall für mich funktioniert. Vielleicht hilft es auch jemandem.
Mein Fall ist der folgende: Ich möchte über jeden Aufzählungsschlüssel iterieren, dann einige Schlüssel filtern und dann auf ein Objekt zugreifen, das Schlüssel als berechnete Werte aus der Aufzählung enthält. So mache ich es also ohne TS-Fehler.
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 !== MyEnum.ONE
)
const allowedLabels = allowedKeys.map((type) => ({
label: LABELS[type]
}))
Ich habe eine EnumUtil-Klasse geschrieben, die eine Typprüfung anhand des Enum-Werts durchführt:
export class EnumUtils {
/**
* Returns the enum keys
* @param enumObj enum object
* @param enumType the enum type
*/
static getEnumKeys(enumObj: any, enumType: EnumType): any[] {
return EnumUtils.getEnumValues(enumObj, enumType).map(value => enumObj[value]);
}
/**
* Returns the enum values
* @param enumObj enum object
* @param enumType the enum type
*/
static getEnumValues(enumObj: any, enumType: EnumType): any[] {
return Object.keys(enumObj).filter(key => typeof enumObj[key] === enumType);
}
}
export enum EnumType {
Number = 'number',
String = 'string'
}
Wie man es benutzt:
enum NumberValueEnum{
A= 0,
B= 1
}
enum StringValueEnum{
A= 'A',
B= 'B'
}
EnumUtils.getEnumKeys(NumberValueEnum, EnumType.number);
EnumUtils.getEnumValues(NumberValueEnum, EnumType.number);
EnumUtils.getEnumKeys(StringValueEnum, EnumType.string);
EnumUtils.getEnumValues(StringValueEnum, EnumType.string);
Ergebnis für NumberValueEnum-Schlüssel: ["A", "B"]
Ergebnis für NumberValueEnum-Werte: [0, 1]
Ergebnis für StringValueEnumkeys: ["A", "B"]
Ergebnis für StringValueEnumvalues: ["A", "B"]
Ich finde diese Lösung eleganter:
for (let val in myEnum ) {
if ( isNaN( parseInt( val )) )
console.log( val );
}
Es zeigt an:
bar
foo
Meine Aufzählung ist wie folgt:
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",
}
Wenn Sie dies tun, geben Sie undefiniert zurück :
UserSorting[UserSorting.SortByUpdatedAt]
Um dieses Problem zu beheben, wähle ich einen anderen Weg, um es mit einem Rohr zu tun:
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;
}
}
Und um es zu benutzen:
return this.enumKeyPipe.transform(UserSorting, [UserSorting.SortByUpdatedAt]);
Wenn Sie eine Aufzählung haben
enum Diet {
KETO = "Ketogenic",
ATKINS = "Atkins",
PALEO = "Paleo",
DGAF = "Whatever"
}
Dann können Sie Schlüssel und Werte erhalten wie:
Object.keys(Diet).forEach((d: Diet) => {
console.log(d); // KETO
console.log(Diet[d]) // Ketogenic
});
Argument of type '(d: Diet) => void' is not assignable to parameter of type '(value: string, index: number, array: string[]) => void'. Types of parameters 'd' and 'value' are incompatible. Type 'string' is not assignable to type 'MyEnum'.(2345)
Ich habe eine Hilfsfunktion geschrieben, um eine Aufzählung aufzulisten:
static getEnumValues<T extends number>(enumType: {}): T[] {
const values: T[] = [];
const keys = Object.keys(enumType);
for (const key of keys.slice(0, keys.length / 2)) {
values.push(<T>+key);
}
return values;
}
Verwendungszweck:
for (const enumValue of getEnumValues<myEnum>(myEnum)) {
// do the thing
}
Die Funktion gibt etwas zurück, das leicht aufgezählt werden kann, und wandelt sich auch in den Aufzählungstyp um.
Mit einer aktuellen TypeScript-Version können Sie Funktionen wie diese verwenden, um die Aufzählung einem Datensatz Ihrer Wahl zuzuordnen. Beachten Sie, dass Sie mit diesen Funktionen keine Zeichenfolgenwerte definieren können, da sie nach Schlüsseln mit einem Wert suchen, der eine Zahl ist.
enum STATES {
LOGIN,
LOGOUT,
}
export const enumToRecordWithKeys = <E extends any>(enumeration: E): E => (
Object.keys(enumeration)
.filter(key => typeof enumeration[key] === 'number')
.reduce((record, key) => ({...record, [key]: key }), {}) as E
);
export const enumToRecordWithValues = <E extends any>(enumeration: E): E => (
Object.keys(enumeration)
.filter(key => typeof enumeration[key] === 'number')
.reduce((record, key) => ({...record, [key]: enumeration[key] }), {}) as E
);
const states = enumToRecordWithKeys(STATES)
const statesWithIndex = enumToRecordWithValues(STATES)
console.log(JSON.stringify({
STATES,
states,
statesWithIndex,
}, null ,2));
// Console output:
{
"STATES": {
"0": "LOGIN",
"1": "LOGOUT",
"LOGIN": 0,
"LOGOUT": 1
},
"states": {
"LOGIN": "LOGIN",
"LOGOUT": "LOGOUT"
},
"statesWithIndex": {
"LOGIN": 0,
"LOGOUT": 1
}
}
Hier gibt es bereits viele Antworten, aber ich denke, ich werde meine Lösung trotzdem auf den Stapel werfen.
enum AccountType {
Google = 'goo',
Facebook = 'boo',
Twitter = 'wit',
}
type Key = keyof typeof AccountType // "Google" | "Facebook" | "Twitter"
// this creates a POJO of the enum "reversed" using TypeScript's Record utility
const reversed = (Object.keys(AccountType) as Key[]).reduce((acc, key) => {
acc[AccountType[key]] = key
return acc
}, {} as Record<AccountType, string>)
Zur Klarheit:
/*
* reversed == {
* "goo": "Google",
* "boo": "Facebook",
* "wit": "Twitter",
* }
* reversed[AccountType.Google] === "Google" 👍
*/
Referenz für TypeScript Record
Eine nette Hilfsfunktion:
const getAccountTypeName = (type: AccountType) => {
return reversed[type]
};
// getAccountTypeName(AccountType.Twitter) === 'Twitter'
Es ist nicht genau die Antwort auf Ihre Frage, aber es ist ein Trick, um Ihr Problem anzugehen.
export module Gender {
export enum Type {
Female = 1,
Male = 2
};
export const List = Object.freeze([
Type[Type.Female] ,
Type[Type.Male]
]);
}
Sie können Ihr Listenmodell beliebig erweitern.
export const List = Object.freeze([
{ name: Type[Type.Female], value: Type.Female } ,
{ name: Type[Type.Male], value: Type.Male }
]);
Jetzt können Sie es folgendermaßen verwenden:
for(const gender of Gender.List){
console.log(gender.name);
console.log(gender.value);
}
oder:
if(i === Gender.Type.Male){
console.log("I am a man.");
}
getAllEnumValues
undgetAllEnumKeys
für Ihren Zweck