Как программно перечислять тип enums в TypeScript 0.9.5?

Скажем, у меня есть перечисление TypeScript, MyEnum, как показано ниже:

enum MyEnum { First, Second, Third } 

Что было бы лучшим способом в TypeScript 0.9.5 для создания массива значений enum? Пример:

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

Это выход JavaScript этого enums:

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

Что такое объект:

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

Имена участников

Чтобы получить имена членов enums, мы можем отфильтровать ключи объекта, когда соответствующее значение является числом. При этом будут найдены имена с одинаковым значением:

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

Содержит: ["First", "Second", "Third"]

Ценности участника

Чтобы получить значения элемента enums, мы можем фильтровать значения объекта любым числом:

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

Содержит: [0, 1, 2]

Класс расширения

Я думаю, что лучший способ сделать это – создать свои собственные функции (например, EnumEx.getNames(MyEnum) ). Вы не можете добавить функцию к перечислению.

 class EnumEx { private constructor() { } static getNamesAndValues(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(e: any) { return Object.keys(e) .map(k => e[k]) .filter(v => typeof v === "number") as T[]; } } 

С помощью TypeScript> = 2.4 вы можете определить enums строк:

 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); 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

(*) Полиполк, необходимый для старых браузеров, см. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values#Browser_compatibility

Существует нет понятия RTTI (информация о типе времени выполнения) в TypeScript (think: reflection), поэтому для этого требуется знание переписанного JavaScript. Итак, предположим, что TypeScript 0.95:

 enum MyEnum { First, Second, Third } 

будет выглядеть так:

 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 для заполнения списка вариантов, я бы использовал простой старый массив. Перечисление не является правильным выбором здесь, каламбур. objective TypeScript – генерировать идиоматический, довольно JavaScript. Использование перечислений таким образом не сохраняет эту цель.

Вы можете добавлять функции для получения имен и индексов enums:

 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] Во- 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, а не подвергать их экспортированной функции, но поскольку экспортированные члены являются членами enums, возможно, что они понятны как функции, поэтому их не путать с фактическими членами enums.

Было бы неплохо, если бы TypeScript генерировал нечто подобное автоматически для всех перечислений.

Я использовал решение, предложенное Дэвидом Шерретом, и написал библиотеку npm, в которой вы можете использовать имена enum-values

Git: значения enum

 // 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); 
 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 =  (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); 

Ответ Джо только заставило меня понять, что гораздо легче полагаться на первые 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)) 

Один лайнер для получения списка записей (объекты / пары с ключом):

 Object.keys(MyEnum).filter(a=>a.match(/^\D/)).map(name=>({name, value: MyEnum[name] as number})); 
  • Инициализаторы типа TypeScript и поля
  • Как инициализировать объект TypeScript с помощью объекта JSON
  • Как получить имена записей enums TypeScript?
  • Использование плагина jQuery в TypeScript
  • Как использовать jQuery с TypeScript
  • Typcript: не может получить доступ к значению элемента в унаследованном конструкторе classа
  • Внедрение интерфейса TypeScript с сигнатурой голосовой функции и другими полями
  • Угловое redirect на страницу входа в систему
  • Импорт узлов-модhive с помощью TypeScript
  • Typcript - расширение classа ошибок
  • Что такое знак вопроса в имени параметра Typcript
  • Давайте будем гением компьютера.