TypeScript - Enums



Enums in TypeScript allow you to define a set of named constants. An enum is a way of giving more friendly names to sets of numeric values.

Each enum member has a value associated with it. The value can be either constant or computed. The member value can be a numeric or string value.

The Enum type in TypeScript is a user-defined data type. TypeScript has some features that are not the type-level extension of the JavaScript. Enum is one of the such few features along with type guards or union.

enum enumName {
   // Enum members
}

The enums in TypeScript can be categorized in the following three types –

  • Numeric enums

  • String enums

  • Heterogeneous enums

Numeric Enums

In this type of enum, members of an enum are assigned numeric values. Numeric enums possess an auto-increment nature. For instance, if we assign the number 5 to the first constant variable of the enum, then the following constant variables assign with values incremented by one, like 6 to the second member of the enum, 7 to the next, and so on.

Example 1: Default numeric enums

By default, enums in TypeScript are numeric. The first member is assigned a value of 0, and subsequent members are incremented by 1.

enum Weekday {
  Monday,
  Tuesday,
  Wednesday,
  Thursday,
  Friday,
}
console.log(Weekday.Monday);
console.log(Weekday.Tuesday);
console.log(Weekday.Wednesday);
console.log(Weekday.Thursday);
console.log(Weekday.Friday);

On compiling, it will generate the following JavaScript code –

var Weekday;
(function (Weekday) {
    Weekday[Weekday["Monday"] = 0] = "Monday";
    Weekday[Weekday["Tuesday"] = 1] = "Tuesday";
    Weekday[Weekday["Wednesday"] = 2] = "Wednesday";
    Weekday[Weekday["Thursday"] = 3] = "Thursday";
    Weekday[Weekday["Friday"] = 4] = "Friday";
})(Weekday || (Weekday = {}));
console.log(Weekday.Monday);
console.log(Weekday.Tuesday);
console.log(Weekday.Wednesday);
console.log(Weekday.Thursday);
console.log(Weekday.Friday);

The output of the above example code is as follows –

0
1
2
3
4

Notice that the first member is initialized with 0 and the subsequent members are incremented by the 1.

Example 2: Initiated numeric enums

In the below example, we have created an enum type named Color. Inside Color, three const variables are created with names Red, Yellow, and Green. We have initialized the first member and left other members for auto increment.

enum Color{
  Red = 10,
  Yellow,
  Green,
}
//print const variables values
console.log(Color.Red);
console.log(Color.Yellow);
console.log(Color.Green);

On compiling, it will generate the following JavaScript code –

var Color;
(function (Color) {
    Color[Color["Red"] = 10] = "Red";
    Color[Color["Yellow"] = 11] = "Yellow";
    Color[Color["Green"] = 12] = "Green";
})(Color || (Color = {}));
//print const variables values
console.log(Color.Red);
console.log(Color.Yellow);
console.log(Color.Green);

The output of the above example code is as follows –

10
11
12

Example 3: Fully initialized numeric enums

We can also set the values of all members of an enum. In the example below, we have initialized all member of the enum HttpStatus.

enum HttpStatus {
  Success = 200,
  NotFound = 404,
  InternalServerError = 500,
}
console.log(HttpStatus.Success);
console.log(HttpStatus.NotFound);
console.log(HttpStatus.InternalServerError);

On compiling, it will generate the following JavaScript code –

var HttpStatus;
(function (HttpStatus) {
    HttpStatus[HttpStatus["Success"] = 200] = "Success";
    HttpStatus[HttpStatus["NotFound"] = 404] = "NotFound";
    HttpStatus[HttpStatus["InternalServerError"] = 500] = "InternalServerError";
})(HttpStatus || (HttpStatus = {}));
console.log(HttpStatus.Success);
console.log(HttpStatus.NotFound);
console.log(HttpStatus.InternalServerError);

The output of the above example code is as follows –

200
404
500

String Enums

String enums are similar to numeric ones except that values of enums members are assigned with strings instead of numeric ones. The string enums do not possess auto-increment behavior.

Example

The following example creates an enum TrafficLight with three members. The members are initialized with string literals.

enum TrafficLight {
  Red = "stop",
  Yellow = "caution",
  Green = "go",
}
console.log(TrafficLight.Red);
console.log(TrafficLight.Yellow);
console.log(TrafficLight.Green);

On compiling, it will generate the following JavaScript code –

var TrafficLight;
(function (TrafficLight) {
    TrafficLight["Red"] = "stop";
    TrafficLight["Yellow"] = "caution";
    TrafficLight["Green"] = "go";
})(TrafficLight || (TrafficLight = {}));
console.log(TrafficLight.Red);
console.log(TrafficLight.Yellow);
console.log(TrafficLight.Green);

The output of the above example code is as follows –

stop
caution
go

Heterogeneous Enums

This is a combination of both numeric and string enums. That is, in this type of enum, we can assign both string values or numeric values to its members.

Example

In the below example, we have created an enum type of Student. Inside the student are three const variables: Name, Gender, and Mobile. Name and Gender are of literal string types, whereas Mobile is of numeric value.

enum student{
  Name = "srujana",
  Gender = "female",
  Mobile = 901234567,
}
console.log(student.Name);
console.log(student.Gender);
console.log(student.Mobile);

On compiling, it will generate the following JavaScript code –

var student;
(function (student) {
    student["Name"] = "Srujana";
    student["Gender"] = "Female";
    student[student["Mobile"] = 901234567] = "Mobile";
})(student || (student = {}));
console.log(student.Name);
console.log(student.Gender);
console.log(student.Mobile);

The output of the above example code is as follows –

Srujana
Female
901234567

Enums at runtime

The enums are real objects that exist at run time. In the below example, the enum E is passed as parameter object to a function. It works, since 'E' has a property named 'y' which is a number.

enum En {
  x,
  y,
  z,
}
 
function func(obj: { y: number }) {
  return obj.y;
}
console.log(func(En));
console.log(typeof En);

On compiling, it will generate the following JavaScript code.

var En;
(function (En) {
    En[En["x"] = 0] = "x";
    En[En["y"] = 1] = "y";
    En[En["z"] = 2] = "z";
})(En || (En = {}));
function func(obj) {
    return obj.y;
}
console.log(func(En));
console.log(typeof En);

The output of the above code is as follows –

1
object

Enums at compile time

When TypeScript enums are compiled, they are converted to JavaScript objects. The object will have a property for each enum member, and the value of each property will be the enum member's value.

The numeric and string enum members behave differently at the compilation. The numeric members are mapped bi-directionally to its corresponding JavaScript object property while string members are mapped uni-directionally to its runtime object property.

enum Enum {
  Name = 'John Doe',
  Age = 32,
}

The above TypeScript code will be compiled to the following JavaScript code –

var Enum;
(function (Enum) {
    Enum["Name"] = "John Doe";
    Enum[Enum["Age"] = 32] = "Age";
})(Enum || (Enum = {}));

Please note that the after compilation, the Name member get mapped unidirectionally and Age member get mapped bi-directionally to its corresponding runtime object properties.

Const Enums

The const enums are special enums in TypeScript that are completely removed during the compilation. These emums are not included in the compiled JavaScript output.

Reverse Mapping

As discussed above that the numeric enum members after compilation get mapped bidirectionally with its runtime object property. This is known as reverse mapping.

enum Enum {
  A = 1,
}
console.log(Enum.A)
console.log(Enum['A'])
console.log(Enum[1]);

On compiling, it will generate the following JavaScript code.

var Enum;
(function (Enum) {
    Enum[Enum["A"] = 1] = "A";
})(Enum || (Enum = {}));
console.log(Enum.A);
console.log(Enum['A']);
console.log(Enum[1]);

The output of the above code is as follows –

1
1
A

Ambient enums

In TypeScript, ambient enums are used to describe the shape of the already existing enum types. The ambient enums don't generate any JavaScript code. To declare an ambient enum, you can use the declare keyword. Look at the below example –

declare enum Fruit {
    Apple,
    Orange,
    Banana,
}

The above code declares the shape of the enum without generating the JavaScript code. It means you can use the Fruit enum in TypeScript code but will not be included in compiled JavaScript code.

Object vs. Enums

An object with as const could suffice the need of the enums. So in modern TypeScript, you may not need enums. When an object could work as enums why to use a different type and also the objects align the state of the JavaScript.

Let's look at the examples of enums and object with as const.

// enum
enum EWeekend {  
  Saturday,  
  Sunday,
}  
console.log(EWeekend.Saturday)
// object with as const
const OWeekend = {
    Saturday: 0,
    Sunday: 1,
} as const;
console.log(OWeekend.Saturday);

On compiling, it will generate the following JavaScript code –

// enum
var EWeekend;
(function (EWeekend) {
    EWeekend[EWeekend["Saturday"] = 0] = "Saturday";
    EWeekend[EWeekend["Sunday"] = 1] = "Sunday";
})(EWeekend || (EWeekend = {}));
console.log(EWeekend.Saturday);
// object with as const
const OWeekend = {
    Saturday: 0,
    Sunday: 1,
};
console.log(OWeekend.Saturday);

The output of the above example code is as follows –

0
0

Using enum as a function parameter

We can use the enum as a parameter in the function definition.

enum Color {
  Red,
  Green,
  Blue,
}
function printColor(color: Color): void {
  console.log(color);
}
printColor(Color.Red); // Prints 0 to the console

In the above example, the function printColor() takes a parameter of type Color. It returns nothing but logs the color in the console.

On compiling, it will generate the following JavaScript code –

var Color;
(function (Color) {
    Color[Color["Red"] = 0] = "Red";
    Color[Color["Green"] = 1] = "Green";
    Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {}));
function printColor(color) {
    console.log(color);
}
printColor(Color.Red); // Prints 0 to the console

The above example code will produce the following output –

0
Advertisements