type switch qué enum enums typescript

enums - switch - ¿Cómo enumerar programáticamente un tipo de enumeración en TypeScript 0.9.5?



typescript enum to string (9)

Con TypeScript> = 2.4 puede definir enumeraciones de cadenas:

enum Color { RED = ''Red'', ORANGE = ''Orange'', YELLOW = ''Yellow'', GREEN = ''Green'', BLUE = ''Blue'', INDIGO = ''Indigo'', VIOLET = ''Violet'' }

Salida JavaScript ES5:

var Color; (function (Color) { Color["RED"] = "Red"; Color["ORANGE"] = "Orange"; Color["YELLOW"] = "Yellow"; Color["GREEN"] = "Green"; Color["BLUE"] = "Blue"; Color["INDIGO"] = "Indigo"; Color["VIOLET"] = "Violet"; })(Color || (Color = {}));

Que es un objeto como este:

const Color = { "RED": "Red", "ORANGE": "Orange", "YELLOW": "Yellow", "GREEN": "Green", "BLUE": "Blue", "INDIGO": "Indigo", "VIOLET": "Violet" }

Por lo tanto, en el caso de las enumeraciones de cadenas, no es necesario filtrar cosas, Object.keys(Color) y Object.values(Color) (*) son suficientes:

const colorKeys = Object.keys(Color); console.log(''colorKeys ='', colorKeys); // ["RED","ORANGE","YELLOW","GREEN","BLUE","INDIGO","VIOLET"] const colorValues = Object.values(Color); console.log(''colorValues ='', colorValues); // ["Red","Orange","Yellow","Green","Blue","Indigo","Violet"] colorKeys.map(colorKey => { console.log(`color key = ${colorKey}, value = ${Color[colorKey]}`); }); /* color key = RED, value = Red color key = ORANGE, value = Orange color key = YELLOW, value = Yellow color key = GREEN, value = Green color key = BLUE, value = Blue color key = INDIGO, value = Indigo color key = VIOLET, value = Violet */

Ver ejemplo en línea en el parque de juegos de TypeScript

(*) Se necesita Polyfill para navegadores antiguos, consulte https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values#Browser_compatibility

Supongamos que tengo una enumeración de TypeScript, MyEnum, de la siguiente manera:

enum MyEnum { First, Second, Third }

¿Cuál sería la mejor manera en TypeScript 0.9.5 para producir una matriz de valores enum? Ejemplo:

var choices: MyEnum[]; // or Array<MyEnum> choices = MyEnum.GetValues(); // plans for this? choices = EnumEx.GetValues(MyEnum); // or, how to roll my own?


Esta es la salida de JavaScript de esa enumeración:

var MyEnum; (function (MyEnum) { MyEnum[MyEnum["First"] = 0] = "First"; MyEnum[MyEnum["Second"] = 1] = "Second"; MyEnum[MyEnum["Third"] = 2] = "Third"; })(MyEnum || (MyEnum = {}));

Que es un objeto como este:

Object { 0: "First", 1: "Second", 2: "Third", First: 0, Second: 1, Third: 2 }

Nombres de miembros

Para obtener los nombres de los miembros enum, podemos filtrar las claves del objeto para cuando el valor correspondiente sea un número. Al hacer esto, se asegura que se encuentren nombres con el mismo valor:

const names = Object.keys(MyEnum) .filter(k => typeof MyEnum[k] === "number") as string[];

Contiene: ["First", "Second", "Third"]

Valores de los miembros

Mientras que para obtener los valores del miembro enum, podemos filtrar los valores del objeto por cualquier cosa que sea un número:

const values = Object.keys(MyEnum) .map(k => MyEnum[k]) .filter(v => typeof v === "number") as number[];

Contiene: [0, 1, 2]

Clase de extensión

Creo que la mejor manera de hacerlo es crear tus propias funciones (por ejemplo, EnumEx.getNames(MyEnum) ). No puede agregar una función a una enumeración.

class EnumEx { private constructor() { } static getNamesAndValues<T extends number>(e: any) { return EnumEx.getNames(e).map(n => ({ name: n, value: e[n] as T })); } static getNames(e: any) { return Object.keys(e).filter(k => typeof e[k] === "number") as string[]; } static getValues<T extends number>(e: any) { return Object.keys(e) .map(k => e[k]) .filter(v => typeof v === "number") as T[]; } }


No existe un concepto de RTTI (información de tipo de tiempo de ejecución) en mecanografiado (think: reflection), por lo que para ello, se requiere el conocimiento del javascript transpilado. Entonces, suponiendo que mecanografia 0.95:

enum MyEnum { First, Second, Third }

se convierte en:

var MyEnum; (function(MyEnum) { MyEnum[MyEnum["First"] = 0] = "First"; MyEnum[MyEnum["Second"] = 1] = "Second"; MyEnum[MyEnum["Third"] = 2] = "Third"; }

Por lo tanto, esto se modela como un objeto normal en javascript, donde MyEnum.0 == "First" y MyEnum.First == 0 . Entonces, para enumerar todos los nombres enum, necesita obtener todas las propiedades que pertenecen al objeto y que tampoco son números:

for (var prop in MyEnum) { if (MyEnum.hasOwnProperty(prop) && (isNaN(parseInt(prop)))) { console.log("name: " + prop); } }

Ok, entonces ahora que te dije cómo hacerlo, puedo decirte que esta es una mala idea . No está escribiendo un lenguaje administrado, por lo que no puede traer estos hábitos. Todavía es simplemente antiguo javascript. Si quisiera utilizar una estructura en javascript para rellenar algún tipo de lista de opciones, usaría una matriz antigua simple. Una enumeración no es la elección correcta aquí, juego de palabras. El objetivo de la mecanografía es generar javascript idiomático, bonito. Usar enumeraciones de esta manera no preserva este objetivo.


Puede agregar funciones para obtener los nombres y los índices de la enumeración:

enum MyEnum { First, Second, Third } namespace MyEnum { function isIndex(key):boolean { const n = ~~Number(key); return String(n) === key && n >= 0; } const _names:string[] = Object .keys(MyEnum) .filter(key => !isIndex(key)); const _indices:number[] = Object .keys(MyEnum) .filter(key => isIndex(key)) .map(index => Number(index)); export function names():string[] { return _names; } export function indices():number[] { return _indices; } } console.log("MyEnum names:", MyEnum.names()); // Prints: MyEnum names: ["First", "Second", "Third"] console.log("MyEnum indices:", MyEnum.indices()); // Prints: MyEnum indices: [0, 1, 2]

Tenga en cuenta que solo podría exportar los _names y _indices lugar de exponerlos a través de una función exportada, pero debido a que los miembros exportados son miembros de la enumeración, es más claro tenerlos como funciones para que no se confundan con los miembros enum reales.

Sería bueno si Typescript generara algo así automáticamente para todas las enumeraciones.


Si desea asociar valores de cadenas a su enumeración, estos métodos no funcionan. Para tener una función genérica, puede hacer:

function listEnum(enumClass) { var values = []; for (var key in enumClass) { values.push(enum[key]); } values.length = values.length / 2; return values; }

Es trabajos porque Typescript agregará claves en el primer paso y valores en el segundo paso.

en typescipt es:

var listEnums = <T> (enumClass: any): T[]=> { var values: T[] = []; for (var key in enumClass) { values.push(enumClass[key]); } values.length = values.length / 2; return values; }; var myEnum: TYPE[] = listEnums<TYPE>(TYPE);


Una línea para obtener una lista de entradas (objetos / pares clave-valor):

Object.keys(MyEnum).filter(a=>a.match(/^/D/)).map(name=>({name, value: MyEnum[name] as number}));


Utilicé la solución propuesta por David Sherret y escribí una biblioteca npm. Puede usar enum-values nombrados ...

Git: enum-values

// Suppose we have an enum enum SomeEnum { VALUE1, VALUE2, VALUE3 } // names will be equal to: [''VALUE1'', ''VALUE2'', ''VALUE3''] var names = EnumValues.getNames(SomeEnum); // values will be equal to: [0, 1, 2] var values = EnumValues.getValues(SomeEnum);


La respuesta de Joe me hizo darme cuenta de que es mucho más fácil confiar en las primeras N teclas numéricas que hacer pruebas más complejas:

function getEnumMembers(myEnum): string[] { let members = [] for(let i:number = 0; true; i++) { if(myEnum[i] === undefined) break members.push(myEnum[i]) } return members } enum Colors { Red, Green, Blue } console.log(getEnumMembers(myEnum))


enum MyEnum { First, Second, Third, NUM_OF_ENUMS } for(int i = 0; i < MyEnum.NUM_OF_ENUMS; ++i) { // do whatever you need to do. }