Enums in TypeScript
What I learned from the Trenches
Introduction
An enum is a set of labeled values called members and is used to organize a group of similar values. A typical data type in many programming languages, enums:
- Improve code readability
- Reduce the chances of making mistakes in your work.
In this article, we’ll be working with a simple enum called Colours, which has the following three members:
enum Colours {
RED = 'RED',
YELLOW = 'YELLOW',
GREEN = 'GREEN'
}
Getting Started
Visit the TypeScript Playground to create an environment without the hassle of installing anything. Follow along with this tutorial by writing code into the left-hand side panel:
On the right-hand side, we’ll be mainly focusing on the Logs menu option. Also, if you’re interested in having a deeper look at how TypeScript is compiled to JavaScript in the JS menu option:
Logs will build up every time code is run, so you might want to clear the logs by clicking this button on the bottom left-hand side of the page:
Enum Flavours
There are two kinds of TypeScript enums: number and string. It’s possible to have a mixed enum with both number or string labeled values; however, I’ve never come across a business case where mixing enum types is helpful.
String
Each member of a string enum initialized with a string literal (assigning string values to enum members), and we can then use them like any other TypeScript enum.
In the following example, we assign strings to each member. Run this code and click the Logs menu option to see the output:
enum Colours {
RED = 'RED',
YELLOW = 'YELLOW',
GREEN = 'GREEN'
}console.log(Colours.RED); // "RED"
console.log(Colours.YELLOW); // "YELLOW"
console.log(Colours.GREEN); // "GREEN"
If you’re interested, you can also see how JavaScript is compiled by clicking on the JS menu option:
To prove to you that we’re returning the values of the Colours enum, re-run the code with these updated string values:
enum Colours {
RED = 'REDISH RED',
YELLOW = 'YELLOWISH YELLOW',
GREEN = 'GREENISH GREEN'
}console.log(Colours.RED); // "REDISH RED"
console.log(Colours.YELLOW); // "YELLOWISH YELLOW"
console.log(Colours.GREEN); // "GREENISH GREEN"
Similarly, we can return string values using square brackets, passing in the member name string:
console.log(Colours['RED']); // "REDISH RED"
console.log(Colours['YELLOW']); // "YELLOWISH YELLOW"
console.log(Colours['GREEN']); // "GREENISH GREEN"
Finally, attempting to access a member that doesn't exist in Colours enum returns undefined:
console.log(Colours['BLUE']); // undefined
Numeric
Numeric enum members have a name and a value. The first member is assigned a value of zero, the next a value of one, etc.
Run this code to log the indexes of the Colours enum members:
enum Colours {
RED,
YELLOW,
GREEN
}console.log(Colours.RED); // 0
console.log(Colours.YELLOW); // 1
console.log(Colours.GREEN); // 2
As you can see, auto-incrementing behavior exists in numeric enums (as opposed to string enums, which doesn’t have this functionality):
It’s possible to assign our values. For example, in the following example, I’ve given numeric values to enum members:
enum Colours {
RED = 1,
YELLOW = 2,
GREEN = 3
}console.log(Colours. RED); // 1
console.log(Colours. YELLOW); // 2
console.log(Colours. GREEN); // 3
Finally, we can assign a value of one to the first member and omit the rest. TypeScript takes care of automatically setting a value of two and three to YELLOW and GREEN members, respectively:
enum Colours {
RED = 1,
YELLOW,
GREEN
}console.log(Colours.RED); // 1
console.log(Colours.YELLOW); // 2
console.log(Colours.GREEN); // 3
Computed Enums
We can call functions to assign enum values.
In the following trivial example, a function accepts the name of a colour and returns a number, checking for the correct value for the colour BLUE:
enum Colours {
RED = 1,
YELLOW,
GREEN,
BLUE = getColourIndex('BLUE')
}function getColourIndex(colour: string): number {
if (colour === 'BLUE') {
return 4;
}
return -1;
}console.log(Colours.RED); // 1
console.log(Colours.BLUE); // 4
Operations
Quite often, we need to perform operations involving enums, such as searching and iterating.
Iterating Enums
Looping through enums is straightforward. In the following example, we iterate through Colours using for-in:
enum Colours {
RED,
YELLOW,
GREEN,
}for (const colour in Colours) {
console.log(colour);
};
Notice that both the names and values of members are logged?
Searching
In this first example, we can find the index of the colour GREEN in the enum, then using that index to find the member:
enum Colours {
RED,
YELLOW,
GREEN
}console.log(Colours[Colours.GREEN]); // "GREEN"
Enum to Array
We can log the member names in one array and values in another array.
In this example, we’ll use the IsNaN operator to filter strings and numbers. Values that don’t convert to Number are deemed enum member names:
enum Colours {
RED,
YELLOW,
GREEN,
};console.log(Object.values(Colours)
.filter(x => !isNaN(Number(x)))); //[0, 1, 2]console.log(Object.values(Colours)
.filter(x => isNaN(Number(x)))); // ['RED','YELLOW','GREEN']
Thanks for reading! Let me know what you think in the comments section below, and don’t forget to subscribe. 👍