Определите количество элементов перечисления TypeScript
Как указано в названии, как вы можете определить количество элементов в перечислении в Typescript, например, в этом примере
enum ExampleEnum {
element1 = 1,
element2 = 2,
element3 = 3,
element4 = 4,
element5 = 5,
element6 = 6
}
var exampleEnumElementCount:number = ?
Как будет определяться счет? В этом случае это должно быть 6
Ответы
Ответ 1
AFAIK, Typescript не предоставляет стандартный метод для получения количества элементов перечисления. Но от его реализации есть аккуратный способ сделать это.
Object.keys(ExampleEnum).length / 2
Ответ 2
Принятый ответ не работает ни в каких версиях перечисления, к которым прикреплено значение. Работает только с самыми основными перечислениями. Вот моя версия, которая работает во всех типах:
export function enumElementCount(enumName: any): number {
let count = 0
for(let item in enumName) {
if(isNaN(Number(item))) count++
}
return count
}
Вот тестовый код для мокко:
it('enumElementCounts', function() {
enum IntEnum { one, two }
enum StringEnum { one = 'oneman', two = 'twoman', three = 'threeman' }
enum NumberEnum { lol = 3, mom = 4, kok = 5, pop = 6 }
expect(enumElementCount(IntEnum)).to.equal(2)
expect(enumElementCount(StringEnum)).to.equal(3)
expect(enumElementCount(NumberEnum)).to.equal(4)
})
Ответ 3
Чтобы дополнительно расширить ответ @Esqarrouth, каждое значение в перечислении будет производить два ключа, за исключением значений перечисления в строке. Например, учитывая следующее перечисление в TypeScript:
enum MyEnum {
a = 0,
b = 1.5,
c = "oooo",
d = 2,
e = "baaaabb"
}
После перехода в Javascript вы получите:
var MyEnum;
(function (MyEnum) {
MyEnum[MyEnum["a"] = 0] = "a";
MyEnum[MyEnum["b"] = 1.5] = "b";
MyEnum["c"] = "oooo";
MyEnum[MyEnum["d"] = 2] = "d";
MyEnum["e"] = "baaaabb";
})(MyEnum || (MyEnum = {}));
Как вы можете видеть, если бы у нас просто было перечисление с записью a
заданным значением 0
, вы получите два ключа; MyEnum["a"]
и MyEnum[0]
. Строковые значения, с другой стороны, просто создают один ключ, как видно из записей c
и e
выше.
Следовательно, вы можете определить фактическое количество, определив, сколько ключей не являются числами; т.е.
var MyEnumCount = Object.keys(MyEnum).map((val, idx) => Number(isNaN(Number(val)))).reduce((a, b) => a + b, 0);
Он просто отображает все ключи, возвращая 1
если ключ является строкой, 0
противном случае, а затем добавляет их, используя функцию Reduce.
Или немного более легкий для понимания метод:
var MyEnumCount = (() => {
let count = 0;
Object.keys(MyEnum).forEach((val, idx) => {
if (Number(isNaN(Number(val)))) {
count++;
}
});
return count;
})();
Вы можете проверить себя на игровой площадке TypeScript https://www.typescriptlang.org/play/
Ответ 4
Если у вас есть перечисление с числами, считающимися из 0
, вы можете вставить заполнитель для размера в качестве последнего элемента, например, так:
enum ERROR {
UNKNOWN = 0,
INVALID_TYPE,
BAD_ADDRESS,
...,
__LENGTH
}
Тогда использование ERROR.__LENGTH
будет соответствовать размеру перечисления, независимо от того, сколько элементов вы вставили.
Вы можете отслеживать произвольное смещение:
enum ERROR {
__START = 7,
INVALID_TYPE,
BAD_ADDRESS,
__LENGTH
}
в этом случае количество значимых ошибок будет ERROR.__LENGTH - (ERROR.__START + 1)
Ответ 5
На данный момент (Typescript v3.1.6) он отлично работает даже со строкой Enum:
Object.keys(ExampleEnum).length
В случае строкового Enum вы просто получите массив строк.