
Ts Enums in TypeScript
Enums in TypeScript
Enums in TypeScript are a way to define a set of named constants, making the code more readable and maintainable. They allow you to represent a collection of related values, which can be either numeric or string-based.
Why Use Enums?
- Better Readability: Enums make your code more expressive, instead of using raw numeric or string values.
- Type Safety: They ensure that only a specific set of values is used, reducing errors.
- Maintainability: Enums group related values together, making your code easier to manage and extend.
Types of Enums in TypeScript
Numeric Enums: The default type for enums is numeric. Each member of the enum is assigned an integer value starting from
0
, unless explicitly specified.String Enums: Instead of numeric values, you can assign string values to the enum members.
Heterogeneous Enums: You can mix numeric and string values in an enum, but it’s generally not recommended for clarity.
1. Numeric Enums
By default, the first value in a numeric enum is assigned 0
, and subsequent values are incremented by 1
. You can also specify values explicitly.
Example: Basic Numeric Enum
enum Direction { Up, // 0 Down, // 1 Left, // 2 Right // 3}let move: Direction = Direction.Up;console.log(move); // 0
Example: Explicit Numeric Values
enum StatusCode { NotFound = 404, Unauthorized = 401, OK = 200}let response: StatusCode = StatusCode.NotFound;console.log(response); // 404
2. String Enums
With string enums, each enum member must be initialized with a string value.
Example: String Enum
enum UserRole { Admin = "ADMIN", User = "USER", Guest = "GUEST"}let role: UserRole = UserRole.Admin;console.log(role); // "ADMIN"
String enums are useful when you need readable, descriptive values that you want to preserve in their raw form (for example, when interacting with APIs).
3. Heterogeneous Enums
Though not recommended for clarity, TypeScript allows mixing string and numeric values within an enum.
Example: Heterogeneous Enum
enum MixedEnum { No = 0, Yes = "YES"}let answer: MixedEnum = MixedEnum.Yes;console.log(answer); // "YES"
4. Enums with Computed and Constant Members
You can use computed values for some enum members, but the first members must be constant.
Example: Computed Enum Members
enum Days { Monday = 1, Tuesday, Wednesday, Thursday = 10, // Set explicitly Friday}console.log(Days.Monday); // 1console.log(Days.Thursday); // 10console.log(Days.Friday); // 11
In the example above, Thursday
is explicitly set to 10
, while the following values (Friday
) are incremented based on the last set value.
5. Reverse Mappings (for Numeric Enums)
TypeScript provides reverse mappings for numeric enums. This means you can use the numeric value to get the name of the enum member.
Example: Reverse Mapping
enum Direction { Up = 1, Down, Left, Right}let directionName: string = Direction[2]; // Using numeric value to get enum nameconsole.log(directionName); // "Down"
Note: Reverse mappings only work for numeric enums. With string enums, reverse mappings aren't available.
6. Using Enums in Functions and Switch Statements
Enums are great for use in conditional logic, such as switch
statements.
Example: Using Enums in Functions
enum TrafficLight { Red = "RED", Yellow = "YELLOW", Green = "GREEN"}function getAction(light: TrafficLight): string { switch (light) { case TrafficLight.Red: return "Stop"; case TrafficLight.Yellow: return "Caution"; case TrafficLight.Green: return "Go"; default: return "Invalid"; }}console.log(getAction(TrafficLight.Red)); // "Stop"
Best Practices with Enums
Prefer String Enums for Readability:
- String enums provide more readable output and avoid potential issues when dealing with reverse mappings.
Avoid Heterogeneous Enums:
- Mixing numeric and string values can reduce clarity and make your code harder to maintain.
Avoid Magic Numbers:
- Use enums instead of magic numbers or strings in your code to improve readability.
Use Enum Members as Constants:
- You can use enum members as constants in your code, avoiding hardcoded values.
Enums vs Constants
While enums provide many benefits, in some cases, you may want to use const
variables or object literals, especially if the values are not intended to be part of an enum and you don't need reverse mapping.
const Directions = { Up: "UP", Down: "DOWN", Left: "LEFT", Right: "RIGHT"} as const;type Direction = typeof Directions[keyof typeof Directions];
This approach is particularly useful for string values that don’t need to be used in reverse mappings or as part of the TypeScript enum feature set.
Conclusion
Enums are a powerful feature in TypeScript, making your code more readable and type-safe. They allow you to work with a set of related constants, ensuring that only valid values are used in your code. Whether using numeric or string enums, they improve the expressiveness of your application and reduce potential errors.