Get the length of an Enum in TypeScript

avatar

Borislav Hadzhiev

Last updated: Feb 15, 2022

banner

Photo from Unsplash

Get the length of an Enum in TypeScript #

To get the length of an enum:

  1. Use the Object.keys() method to get an array containing the enum's keys.
  2. Access the length property on the array.
  3. When working with numeric enums, divide the result by 2, because a reverse mapping is generated.
index.ts
// ✅ 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.

index.ts
// 👇️ ['name', 'age'] console.log(Object.keys({ name: 'Alice', age: 30 }));

However, the output for numeric and string enums is different.

index.ts
// ✅ 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));
Notice that when a numeric enum is passed to the 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.

index.ts
// ✅ 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.

If you're working with mixed enums (ones that contain both string and numeric members), you have to filter out the keys for the reverse mapping.

In other words, we have to exclude the valid numbers from the array of keys.

index.ts
// ✅ 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.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.