DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for TypeScript enum guide: get started in 5 minutes
Erin Schaffer for Educative

Posted on • Originally published at educative.io

TypeScript enum guide: get started in 5 minutes

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?

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;
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

If you want, you can initialize the first numeric value yourself like this:

enum CarType {
    Honda = 1,
    Toyota,
    Subaru,
    Hyundai
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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",
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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,
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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,
}
Enter fullscreen mode Exit fullscreen mode

You can declare the above enum like this:

enum CarType {
    Honda,
    Hyundai,
    Toyota = getCarTypeCode('toyota'),
    Subaru = Toyota * 3
Enter fullscreen mode Exit fullscreen mode

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!

Continue reading about TypeScript

Top comments (0)

🌚 Life is too short to browse without dark mode