Enumerations (or enums) are a supported data type in TypeScript. Enums are used in most object-oriented programming languages like Java and C# and are now available in TypeScript too. They are one of the few features of TypeScript which isn’t a type-level extension of JavaScript. Enums allow you to define a set of named constants. Using them makes it easier to document intent or create a set of distinct cases. Today, we’ll explore the basics of TypeScript enums along with use cases, various enum types, and next steps for your learning.
We’ll cover:
- What is enum in TypeScript?
- Why use enums in TypeScript?
- Enums vs. alternatives
- Numeric enums
- String enums
- Heterogeneous enums
- Reverse mapping with enums
- Const enums
- Computed enums
- What to learn next
What is enum in Typescript?
TypeScript enums allow you to define a set of named constants. Using them can make it easier to document intent or to create a set of distinct cases. Many programming languages, like C, C#, and Java, have an enum
data type, but JavaScript doesn’t. However, TypeScript does. TypeScript has both numeric and string-based enums.
The syntax for enums is as follows:
enum States {
Oregon,
Washington,
Idaho,
Montana,
Wyoming
}
// usage
var region = States.Washington;
Before we look more closely at a few different enum types, let’s discuss the benefits of enums in TypeScript.
Why use enums in TypeScript?
Enums are a great way to organize your code in TypeScript. Let’s look at some pros:
- Provides flexibility making it easier to express and document intentions and use cases
- Saves compile-time and runtime with inline code in JavaScript
- Allows for the creation of memory-efficient custom constants in JavaScript
- Etc.
Enums vs. alternatives
While there are many benefits of using TypeScript enums, there are some times you shouldn’t use them, such as:
- Reassigning or changing enum member values: enums are type-safe and would return compile errors on reassignment
- Recording dynamic values: enums are suited for finite items and help to create a user-defined constants system
- Using variables: enums can’t be used as variables and doing so would return errors
Now, let’s dive deeper into some enum types.
Numeric enums
Numeric enums store string values as numbers. They can be defined using the enum
keyword. Let’s say you wanted to store a set of different types of cars. The following example shows a numeric enum in TypeScript:
enum CarType {
Honda,
Toyota,
Subaru,
Hyundai
}
The enum value CarType
has four values: Honda, Toyota, Subaru, and Hyundai. Enum values start from zero and increment by one for each member, which would look something like this:
Honda = 0
Toyota = 1
Subaru = 2
Hyundai = 3
If you want, you can initialize the first numeric value yourself like this:
enum CarType {
Honda = 1,
Toyota,
Subaru,
Hyundai
}
In the above example, we initialized the first member Honda
with the numeric value of one. The remaining numbers will be incremented by one.
Note: It’s not necessary to assign sequential values to your enum members. You can assign them any values you want.
String enums
String enums are similar to numeric enums, but their enum values are initialized with string values instead of numeric values. String enums have better readability than numeric enums, making it easier to debug your programs.
The following example uses the same info as the numeric enum example, but is represented as a string enum:
enum CarType {
Honda = "HONDA",
Toyota = "TOYOTA",
Subaru = "SUBARU",
Hyundai = "HYUNDAI"
}
// Access String Enum
CarType.Toyota; //returns TOYOTA
CarType['Honda']; //returns HONDA
In the example, we defined the string enum CarType
with the same values as the numeric enum, except the enum values are initialized as string literals.
Note: String enum values need to be individually initialized.
Heterogeneous enums
Heterogeneous enums contain both numeric and string values. Here’s an example:
enum BooleanHeterogeneousEnum {
Yes = 0,
No = "NO",
}
Reverse mapping with enums
You know that num values can be retrieved using their corresponding enum member values. With reverse mapping, you can access the value of a member and a member name from its value. Let’s look at an example:
enum CarType {
Honda = 1,
Toyota,
Subaru,
Hyundai
}
CarType.Subaru; // returns 3
CarType["Subaru"]; // returns 3
CarType[3]; // returns Subaru
CarType[3]
returns its member name “Subaru” because of reverse mapping. Let’s look at another example:
enum CarType {
Honda = 1,
Toyota,
Subaru,
Hyundai
}
console.log(CarType)
You would see the following output in your browser console:
{
'1': 'Honda',
'2': 'Toyota',
'3': 'Subaru',
'4': 'Hyundai',
Honda: 1,
Toyota: 2,
Subaru: 3,
Hyundai: 4
}
Each value of the enum appears two times in the internally stored enum object.
Const enums
You can use const enums to improve the performance of your numeric enums. They are defined using the const
modifier:
const enum Enum {
X = 1
Y = X * 2,
}
Unlike regular enums, const enums are completely removed during compilation. They can only use constant enum expressions and are inlined at use sites.
Computed enums
The value of an enum member can be a constant value or a computed value. The following example includes computed values:
enum CarType {
Honda = 1,
Toyota = getCarTypeCode('toyota'),
Subaru = Toyota * 3,
Hyundai = 10
}
function getCarTypeCode(carName: string): number {
if (carName === 'toyota') {
return 5;
}
}
CarType.Toyota; // returns 5
CarType.Subaru; // returns 15
If the enum includes both computed and constant members, then uninitiated enum members either come first or after other initialized members with numeric constants. This next example will show an error:
enum CarType {
Toyota = getCarTypeCode('toyota'),
Honda, // Error: Enum member must have initializer
Subaru,
Hyundai = Toyota * 3,
}
You can declare the above enum like this:
enum CarType {
Honda,
Hyundai,
Toyota = getCarTypeCode('toyota'),
Subaru = Toyota * 3
What to learn next
TypeScript provides many advantages for client-side developers. It’s easier to pick up than some other alternatives because you can jump in with a JavaScript background. TypeScript enums make it easier to document intent or to create a distinct set of cases.
Now that you know more about different TypeScript enums and their benefits, you’re ready to learn more about advanced TypeScript concepts. Some recommended topics to cover next are:
- Strict types
- Generic functions
- Mapped types
- And much more
To get started learning these concepts, check out Educative’s text-based course, Advanced TypeScript Masterclass. In this course, you’ll explore the advanced features of TypeScript with in-browser coding exercises. By the end, you’ll be more confident in your advanced TypeScript skills, and you’ll be ready to apply them to your next project.
Happy learning!
Top comments (0)