Borislav Hadzhiev
Tue Feb 15 2022·2 min read
Photo by Robson Hatsukami Morgan
To get the length of an enum:
Object.keys()
method to get an array containing the enum's keys.length
property on the array.2
, because a reverse
mapping is generated.// ✅ For String Enums enum Sizes { Small = 'S', Medium = 'M', Large = 'L', } const length1 = Object.keys(Sizes).length; console.log(length1); // 👉️ 3 // ✅ For Numeric Enums enum SizesNumeric { Small, Medium, Large, } const length2 = Object.keys(SizesNumeric).length / 2; console.log(length2); // 👉️ 3 // ✅ For Mixed Enums (both strings and numbers) enum SizesMixed { Small = 1, Medium = 'test', Large = 3, ExtraLarge = 4, } const length3 = Object.keys(SizesMixed).filter((v) => isNaN(Number(v))).length; console.log(length3); // 👉️ 4
Enums in TypeScript are real objects and exist at runtime. This is why we are able to pass an enum to the Object.keys method.
The Object.keys()
method returns an array containing the object's keys.
// 👇️ ['name', 'age'] console.log(Object.keys({ name: 'Alice', age: 30 }));
However, the output for numeric and string enums is different.
// ✅ For String Enums enum Sizes { Small = 'S', Medium = 'M', Large = 'L', } // 👇️ ['Small', 'Medium', 'Large'] console.log(Object.keys(Sizes)); // ✅ For Numeric Enums enum SizesNumeric { Small, Medium, Large, } // 👇️ ['0', '1', '2', 'Small', 'Medium', 'Large'] console.log(Object.keys(SizesNumeric));
Object.keys
method, we get get an array containing the values and the names of the enum, whereas for a string enum, we only get the names.This is because a reverse mapping gets generated only for numeric enums.
The reverse mapping allows us to access a numeric enum's key by a value.
// ✅ For Numeric Enums enum SizesNumeric { Small, Medium, Large, } console.log(SizesNumeric[0]); // 👉️ "Small" console.log(SizesNumeric[1]); // 👉️ "Medium"
This is why we had to divide the length of the array the Object.keys()
method
returns by 2
for numeric enums.
String enum members don't get a reverse mapping generated at all.
In other words, we have to exclude the valid numbers from the array of keys.
// ✅ For Mixed Enums (both strings and numbers) enum SizesMixed { Small = 1, Medium = 'M', Large = 3, ExtraLarge = 4, } const length3 = Object.keys(SizesMixed).filter((v) => isNaN(Number(v))).length; console.log(length3); // 👉️ 4
The filter()
method is there to filter out all of the keys in the array that
are valid numbers (the generated reverse mapping keys).
We don't have to divide by 2
, because we've already excluded all of the keys
that were generated for the reverse mappings.