Это результат JavaScript этого перечисления:
var MyEnum;
(function (MyEnum) {
MyEnum[MyEnum["First"] = 0] = "First";
MyEnum[MyEnum["Second"] = 1] = "Second";
MyEnum[MyEnum["Third"] = 2] = "Third";
})(MyEnum || (MyEnum = {}));
Вот такой объект:
{
"0": "First",
"1": "Second",
"2": "Third",
"First": 0,
"Second": 1,
"Third": 2
}
Члены перечисления со строковыми значениями
В TypeScript 2.4 добавлена возможность для перечислений, возможно, иметь строковые значения членов перечисления. Таким образом, можно получить перечисление, которое будет выглядеть следующим образом:
enum MyEnum {
First = "First",
Second = 2,
Other = "Second"
}
var MyEnum;
(function (MyEnum) {
MyEnum["First"] = "First";
MyEnum[MyEnum["Second"] = 2] = "Second";
MyEnum["Other"] = "Second";
})(MyEnum || (MyEnum = {}));
Получение имен участников
Мы можем посмотреть на приведенный выше пример, чтобы попытаться выяснить, как получить члены перечисления:
{
"2": "Second",
"First": "First",
"Second": 2,
"Other": "Second"
}
Вот что я придумал:
const e = MyEnum as any;
const names = Object.keys(e).filter(k =>
typeof e[k] === "number"
|| e[k] === k
|| e[e[k]]?.toString() !== k
);
Ценности участников
Когда у нас есть имена, мы можем перебрать их, чтобы получить соответствующее значение, выполнив:
const values = names.map(k => MyEnum[k]);
Класс расширения
Я думаю, что лучший способ сделать это - создать свои собственные функции (например EnumEx.getNames(MyEnum)
). Вы не можете добавить функцию в перечисление.
class EnumEx {
private constructor() {
}
static getNamesAndValues(e: any) {
return EnumEx.getNames(e).map(n => ({ name: n, value: e[n] as string | number }));
}
static getNames(e: any) {
return Object.keys(e).filter(k =>
typeof e[k] === "number"
|| e[k] === k
|| e[e[k]]?.toString() !== k
);
}
static getValues(e: any) {
return EnumEx.getNames(e).map(n => e[n] as string | number);
}
}
for of
оператор вместоfor in
С TypeScript> = 2.4 вы можете определить перечисления строк:
enum Color { RED = 'Red', ORANGE = 'Orange', YELLOW = 'Yellow', GREEN = 'Green', BLUE = 'Blue', INDIGO = 'Indigo', VIOLET = 'Violet' }
Вывод 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 = {}));
Вот такой объект:
const Color = { "RED": "Red", "ORANGE": "Orange", "YELLOW": "Yellow", "GREEN": "Green", "BLUE": "Blue", "INDIGO": "Indigo", "VIOLET": "Violet" }
Таким образом, в случае строковых перечислений нет необходимости фильтровать вещи,
Object.keys(Color)
и достаточноObject.values(Color)
(*):const colorKeys = Object.keys(Color) as (keyof typeof 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 */
См. Онлайн- пример на площадке TypeScript
(*) Polyfill, необходимый для старых браузеров, см. Https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values#Browser_compatibility.
источник
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof Color'. No index signature with a parameter of type 'string' was found on type 'typeof Color'.
Object.keys(Color) as (keyof typeof Color)[]
Вы можете добавить функции для получения имен и индексов перечисления:
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]
Обратите внимание , что вы могли бы просто экспортировать
_names
и_indices
consts , а не подвергая их через экспортируемую функцию, а потому , что экспортируемые члены являются членами перечисления это, возможно , понятнее иметь их как функции , так что они не путать с действительными членами перечислений.Было бы неплохо, если бы TypeScript автоматически генерировал что-то подобное для всех перечислений.
источник
В TypeScript нет концепции RTTI (информация о типе времени выполнения) (думаю: отражение), поэтому для этого требуется знание транслированного JavaScript. Итак, предполагая TypeScript 0.95:
становится:
var MyEnum; (function(MyEnum) { MyEnum[MyEnum["First"] = 0] = "First"; MyEnum[MyEnum["Second"] = 1] = "Second"; MyEnum[MyEnum["Third"] = 2] = "Third"; }
Итак, это моделируется как обычный объект в javascript, где
MyEnum.0 == "First"
иMyEnum.First == 0
. Итак, чтобы перечислить все имена перечислений, вам нужно получить все свойства, которые принадлежат объекту и также не являются числами:for (var prop in MyEnum) { if (MyEnum.hasOwnProperty(prop) && (isNaN(parseInt(prop)))) { console.log("name: " + prop); } }
Хорошо, теперь я рассказал вам, как это сделать, и могу сказать, что это плохая идея . Вы не пишете управляемый язык, поэтому вы не можете привнести эти привычки. Это все еще простой старый JavaScript. Если бы я хотел использовать структуру в JavaScript для заполнения какого-то списка вариантов, я бы использовал простой старый массив. Перечисление здесь не лучший выбор, каламбур. Цель TypeScript - создать идиоматический красивый JavaScript. Использование перечислений таким образом не помогает достичь этой цели.
источник
Я использовал решение, предложенное Дэвидом Шерретом, и написал библиотеку npm, которую вы можете использовать с именем
enum-values
...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);
источник
Однострочник для получения списка записей (объекты / пары ключ-значение):
Object.keys(MyEnum).filter(a=>a.match(/^\D/)).map(name=>({name, value: MyEnum[name] as number}));
источник
enum MyEnum { First, Second, Third, NUM_OF_ENUMS } for(int i = 0; i < MyEnum.NUM_OF_ENUMS; ++i) { // do whatever you need to do. }
источник
Если вы хотите связать строковые значения со своим перечислением, эти методы не работают. Чтобы иметь универсальную функцию, вы можете:
function listEnum(enumClass) { var values = []; for (var key in enumClass) { values.push(enum[key]); } values.length = values.length / 2; return values; }
Это работает, потому что TypeScript добавит ключи на первом этапе и значения на втором этапе.
В TypeScript это:
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);
источник
Ответ Джо заставил меня понять, что намного проще полагаться на первые N цифровых ключей, чем на более сложные проверки:
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))
источник
для nodejs:
const { isNumber } = require('util'); Object.values(EnumObject) .filter(val => isNumber(val)) .map(val => { // do your stuff })
источник
Итерация по перечислению
Для этого лучше всего подходят строковые перечисления. Вот пример:
// This is a string enum enum MyEnum { First = 'First', Second = 'Second', Third = 'Third', } // An enum is a TS concept // However his MyEnum compiles to JS object: // { // "First": "First", // "Second": "Second", // "Third": "Third" // } // Therefore we can get the keys in the following manner: const keysArray = Object.keys(MyEnum); for (const key of keysArray) { console.log(key) } // [LOG]: "First" // [LOG]: "Second" // [LOG]: "Third"
источник