TypeScript Enum

In TypeScript, Enums or enumerations are a set of named constants. Enums make it easier to work with a set of related values by giving them meaningful names, improving code readability and maintainability.

1. Quick Reference for Impatient

An enum can be defined using the enum keyword.

TypeScript supports the following enum types:

  • numeric enums
  • string enums
  • heterogeneous enums (mix different value types in the same enum)
enum Status {
  Active = "ACTIVE",
  Inactive = "INACTIVE"
}

let status: Status = Status.Active;

if (status === Status.Active) {
  console.log("Status is Active");
}

Similarily, a heterogeneous enum can be defined as follows:

enum Status {
  Active = "ACTIVE",
  Inactive = 0
}

2. TypeScript Enum with String Constants

In enum with strings, the enum values are initialized with string values. String enums are the recommended approach in comparison to traditional numeric enums.

When debugging a program, a string value is always more readable than some number. As a best practice, always use string-based enums, until you have a very solid reason for choosing traditional enums over this.

2.1. Enum Syntax

Syntax to create an enum is very similar to other languages.

enum AppStatus {

  ACTIVE = 'ACTIVE',
  INACTIVE = 'INACTIVE',
  ONHOLD = 'ONHOLD'
}

Look at the generated code in JavaScript. It has a generated lookup table like this.

var AppStatus;

(function (AppStatus) {

    AppStatus["ACTIVE"] = "ACTIVE";
    AppStatus["INACTIVE"] = "INACTIVE";
    AppStatus["ONHOLD"] = "ONHOLD";
})(AppStatus || (AppStatus = {}));

2.2. Accessing Enum Values

Use Enum.member or Enum[‘member’] format to access enum member values.

enum AppStatus {
  ACTIVE = 'ACT',
  INACTIVE = 'INACT',
  ONHOLD = 'HLD'
}

//Dot operator
AppStatus.ACTIVE    //ACT
AppStatus.INACTIVE    //INACT

//Using brackets
AppStatus['ACTIVE']   //ACT

//Never use numbers with string based enums
AppStatus[0]      //undefined

2.3. Passing Enum as Method Argument

To pass an enum in functions, declare the argument type of the enum itself.

enum AppStatus {
  ACTIVE = 'ACT',
  INACTIVE = 'INACT',
  ONHOLD = 'HLD'
}

function checkStatus(status: AppStatus): void {

  console.log(status);
}

checkStatus(AppStatus.ONHOLD);

3. Traditional Numeric Enums

Though not recommended, we may come across situations where we need it.

3.1. Syntax

The syntax is pretty simple and old-school. As we have not initialized the values, the transpiler generates lookup table with values assigned in an array index fashion (starting with zero and then incrementing by one for each member).

enum AppStatus {

  ACTIVE,     //0
  INACTIVE,   //1
  ONHOLD      //2
}

If we want to start with any other number, then assign it to the first enum member. All following members will get the value by incrementing one by one.

enum AppStatus {

  ACTIVE = 5,   //5
  INACTIVE,     //6
  ONHOLD        //7
}

It is not necessary to assign sequential values to Enum members. You can assign any value to any element.

enum AppStatus {

  ACTIVE = 1,     //1
  INACTIVE = -1,  //-1
  ONHOLD = 0      //0
}

3.2. Accessing Enum Values

As these are number-based enums, you can use the format enum[index_number] as well, as with Enum.member or Enum[‘member’].

enum AppStatus {
  ACTIVE,
  INACTIVE,
  ONHOLD
}

console.log(AppStatus.ACTIVE);        //0
console.log(AppStatus['INACTIVE']);   //1
console.log(AppStatus[0]);            //ACTIVE

3.3. Enum as Method Argument

To pass an enum in functions, declare the argument type of the enum itself, as follows:

enum AppStatus {
  ACTIVE,
  INACTIVE,
  ONHOLD
}

function checkStatus(status: AppStatus): void {

  console.log(status);
}

checkStatus(AppStatus.ONHOLD);  //2

Please see the value printed '2' in the last statement. It is not very useful in most scenarios, so that’s why string-based enums are preferred and recommended.

4. Reverse Mapping – Convert Value to Enum

Enum in TypeScript supports reverse mapping. It means we can access the enum member name using its value.

4.1. For Numeric Enums

For example, in the following numeric enum, we get the enum member ONHOLD using its value 2. In this code, enum values are not just assigned numbers; they are also assigned reverse mappings from the value to the key.

enum AppStatus {
  ACTIVE = 1,
  INACTIVE,
  ONHOLD
}

console.log(AppStatus[2]);  // INACTIVE

4.2. For String Enums – Convert String to Enum

However, the same approach will not work for string enums because TypeScript doesn’t automatically generate the reverse mapping in the case of string enums. As a result, attempting to access a string enum value using a string key like AppStatus['HLD'] won’t work.

enum AppStatus {

  ACTIVE = 'ACT',
  INACTIVE = 'INACT',
  ONHOLD = 'HLD'
}

console.log(AppStatus['HLD']);  //ERROR: Property 'HLD' does not exist on type 'typeof AppStatus'

To perform reverse mapping with string enums, we need to create our own reverse mapping mechanism as a custom function.

In the following example, we are converting a string to enum. The function stringToEnumValue() takes two parameters:

  • enumObj: is the enum object type we want to perform the reverse lookup on.
  • str: is the string value we want to convert into an enum value.

The function uses Object.keys() method to retrieve an array of keys from the specified enum type and then iterate through those keys and find the first key whose value matches the specified string value. This essentially performs a reverse lookup, searching for a key that matches the provided string value.

In the second line, after the reverse lookup, the function checks if a matching key was found then returns the enum member, else returns undefined.

enum AppStatus {

  ACTIVE = 'ACT',
  INACTIVE = 'INACT',
  ONHOLD = 'HLD'
}

function stringToEnumValue<T>(enumObj: T, str: string): T[keyof T] | undefined {
    const key = Object.keys(enumObj).find(k => enumObj[k] === str);
    return key !== undefined ? enumObj[key] : undefined;
}

const appStatusStringValue = "INACT";
const appStatusEnumValue = stringToEnumValue(AppStatus, appStatusStringValue);

if (appStatusEnumValue !== undefined) {
    console.log("Converted enum value:", appStatusEnumValue); // Output: Converted enum value: INACTIVE
} else {
    console.log("Invalid enum string.");
}

In this way, we can check if a string is in the enum in TypeScript.

Drop me your questions in the comments section.

Happy Learning !!

Comments

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode