Определите количество элементов перечисления 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 вы просто получите массив строк.