Find out the quantity of enum elements in TypeScript

Exploring the realm of TypeScript, one may wonder about determining the number of elements in an enum. Consider this example:

enum ExampleEnum {

    element1 = 1,
    element2 = 2,
    element3 = 3,
    element4 = 4,
    element5 = 5,
    element6 = 6

}

var exampleEnumElementCount:number = ? 

So how exactly can we figure out the count of elements in this Enum? In the given case, it should be 6.

Answer №1

Getting the count of enum elements in Typescript can be achieved using a workaround method. By utilizing the implementation of enum reverse mapping, you can use the following code snippet:

Object.keys(ExampleEnum).length / 2;

It is important to note that for string enums, dividing by two is not necessary as no reverse mapping properties are generated:

Object.keys(StringEnum).length;

If your enum contains both string and numeric values, you can calculate the count using the following approach:

Object.keys(ExampleEnum).filter(isNaN).length;

Answer №2

When working with an enum that starts counting from 0, you have the option to add a placeholder for the size as the last element, like this:

enum ERROR {
  UNKNOWN = 0,
  INVALID_TYPE,
  BAD_ADDRESS,
  ...,
  __LENGTH
}

By utilizing ERROR.__LENGTH, you can easily determine the total size of the enum, regardless of how many elements are added.

If you need to introduce an arbitrary offset, you can include it in the enum definition:

enum ERROR {
  __START = 7,
  INVALID_TYPE,
  BAD_ADDRESS,
  __LENGTH
}

In this scenario, the number of meaningful errors would be calculated as

ERROR.__LENGTH - (ERROR.__START + 1)

Answer №3

The solution provided may not function correctly with enum versions containing attached values, but my revised version caters to all types of enums:

export function countEnumElements(enumType: any): number {
    let count = 0
    for(let key in enumType) {
        if(isNaN(Number(key))) count++
    }
    return count
}

Test code example using Mocha:

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(countEnumElements(IntEnum)).to.equal(2)
    expect(countEnumElements(StringEnum)).to.equal(3)
    expect(countEnumElements(NumberEnum)).to.equal(4)
})

Answer №4

Expanding on the response provided by @Esqarrouth, it is important to note that in an enum, each value except for string enums will result in two keys being generated. For instance, consider the following enum defined in TypeScript:

enum MyEnum {
    a = 0, 
    b = 1.5,
    c = "oooo",
    d = 2,
    e = "baaaabb"
}

Upon transpilation into Javascript, the resulting code will look like this:

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 = {}));

In the above example, you can observe that having an entry like a assigned the value 0 results in two corresponding keys; MyEnum["a"] and MyEnum[0]. Conversely, string values such as entries c and e only generate one key.

To determine the total count of keys, one can identify the Keys that are not numeric, thus:

var MyEnumCount = Object.keys(MyEnum).map((val, idx) => Number(isNaN(Number(val)))).reduce((a, b) => a + b, 0);

This code snippet iterates over all keys, assigning a value of 1 to string keys and 0 to numerical keys, then aggregates them using the reduce function.

An alternative method that may be easier to comprehend is as follows:

var MyEnumCount = (() => {
    let count = 0;
    Object.keys(MyEnum).forEach((val, idx) => {
        if (Number(isNaN(Number(val)))) {
            count++;
        }
    });
    return count;
})();

You can experiment with this concept on the TypeScript playground available at https://www.typescriptlang.org/play/

Answer №5

To simplify the process, we first check for NaN and then determine the length. Let's explore this approach using integer-based enums and string-based enums.

  1. Integer based enum:

    enum Color {
      Red = 0,
      Green,
      Blue
    }
    
    console.log(Object.keys(Color)) /// output: ["0", "1", "2", "Red", "Green", "Blue"] 
    

Therefore, the length is:

const enumLength = Object.keys(Color).filter(key => isNaN(Number(key))).length;
console.log(enumLength); /// output: 3
  1. String based enum:

    enum Color {
      Red = 'red',
      Green = 'green',
      Blue  = 'blue'
    }
    
    console.log(Object.keys(Color)) /// output: ["Red", "Green", "Blue"]
    const enumLength = Object.keys(Color).filter(key => isNaN(Number(key))).length;
    console.log(enumLength); /// **output: 3**
    

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Trouble with HammerJs swipeRight and swipeLeft in Angular 8 when using overflow:auto

I need assistance with my mobile application that requires swipe events within a scrollable container. Currently, when I use (swipeRight)="" or (swipeLeft)="", the events work effectively but it disables scrolling within the container. I attempted to util ...

The Ionic 5 app features a white iframe that functions perfectly on the web platform

Whenever I run my web application's function, the iframe is displayed. However, on Android, all I see is a white screen. Can anyone assist with resolving this issue? HMTL html <ion-content> <ion-button expand="full" color="warning" (clic ...

I am unable to refresh the table data in Angular

Here is the code that I am currently working with: I am facing an issue where my webpage is not updating its data after performing delete or any other operations. The user list is not being displayed in the data. Despite my attempts, I have been unable to ...

What is the most effective way to properly define class attributes?

Recently, I came across some code that I inherited and I'm currently working on getting it transpiled and up and running. So, as I was inspecting the components/TableAsset.tsx file, I stumbled upon these lines of code: import { Table } from "antd"; c ...

Guide to setting the order of rendering in React applications

I am currently working with a .tsx file that renders two components: export default observer(function MyModule(props: MyModuleProps) { .... return ( <div> <TopPart></TopPart> <LowerPart>< ...

Unit testing Angular components can often uncover errors that would otherwise go unnoticed in production. One common

I need assistance writing a simple test in Angular using Shallow render. In my HTML template, I am utilizing the Async pipe to display an observable. However, I keep encountering the following error: Error: InvalidPipeArgument: '() => this.referenc ...

Fast screening should enhance the quality of the filter options

Looking to enhance the custom filters for a basic list in react-admin, my current setup includes: const ClientListsFilter = (props: FilterProps): JSX.Element => { return ( <Filter {...props}> <TextInput label="First Name" ...

Error in Angular Apollo V3: Jest unable to locate module 'apollo-angular'

After recently updating angular apollo from version 2.6.0 to v3.0.0, my tests have been broken. I use jest for unit testing, and although the application compiles and runs without any issues, my tests cannot import any dependencies from 'apollo-angul ...

Navigating in Angular when encountering an HTTP 401 Error

Here is the code snippet I've been working on: AuthenticationService import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { BehaviorSubject, Observable } from 'rxjs'; im ...

Are npm @types packages causing issues in Visual Studio?

Nowadays, TypeScript's type packages are typically found in node packages with the format @types/packagename. Strangely, Visual Studio, despite its support for npm packages, appears to be unable to locate them: https://i.sstatic.net/7tOK1.png The s ...

Obtaining data from a Nested Json file in Angular 5

Encountering difficulties retrieving data from nested JSON. Error: 1. <h3>{{sampledata}}</h3> displaying [object Object] 2. <p>{{sampleDataModel.Title}}</p> ERROR TypeError: Cannot read property 'Title' of undefined ...

Retrieve the precise generic type from a function

Consider this scenario: There is a function called createObj that takes an object as a parameter of type ExampleType. It then creates a new object with a property def which contains the provided object. The goal is for it to return a type that matches the ...

experimenting with a TypeScript annotation

I have created a simple decorator that can trigger either stopPropagation() or preventDefault() based on certain conditions. I have thoroughly tested this decorator in my application and am confident that it works correctly. However, I encountered an issue ...

The new experimental appDir feature in Next.js 13 is failing to display <meta> or <title> tags in the <head> section when rendering on the server

I'm currently experimenting with the new experimental appDir feature in Next.js 13, and I've encountered a small issue. This project is utilizing: Next.js 13 React 18 MUI 5 (styled components using @mui/system @emotion/react @emotion/styled) T ...

Validating user input on the server side in a Typescript and .NET Core application

I am working on a .NET Core app with Angular and I need to implement server-side validation using TypeScript. Specifically, I have a button on the screen that should only trigger an action if certain fields have valid values. These values need to be check ...

Assign each active class name to the Tab components in React

I'm struggling to figure out how to apply an active class to each tab title so that it can have a distinct style when clicked. I'm looking for solutions on how to achieve this within these components, any help is greatly appreciated. App.tsx imp ...

Load images in advance using the link tag to eliminate the warning (html/Javascript)

After attempting to insert <link rel="preload" as="image" href="path"> into the <head>, I received a warning in the console. {path to image} was preloaded using link preload but not used within a few seconds from t ...

How can we add a key:value pair at a specific position in an array in Angular 2 using Typescript?

Is there a way to insert a key value pair at a specific index in an array? I am currently struggling with this task. Here is the code I have been working on: this.quiz.push( { "question-no":this.no, "Ans":this.ans } I require this functionality to ...

As soon as you start typing in the TextInput field, the keyboard abruptly disappears

Whenever I attempt to input a value into my TextInput, the keyboard on mobile closes and the value does not show up in the TextField. This issue arises when I utilize the useState hook to store the input in a variable. Is there a way to resolve this behav ...

Can one mimic a TypeScript decorator?

Assuming I have a method decorator like this: class Service { @LogCall() doSomething() { return 1 + 1; } } Is there a way to simulate mocking the @LogCall decorator in unit tests, either by preventing it from being applied or by a ...