TypeScript enums are one of the language’s most powerful features for creating organized, type-safe code. In this guide, we’ll explore everything you need to know about TypeScript enums, from basic usage to advanced patterns.
Enums help you define a set of named constants, making your code more maintainable and self-documenting. Whether you’re new to TypeScript or looking to deepen your understanding, this guide will equip you with the knowledge to use enums effectively.
Table of Contents
- What are TypeScript Enums?
- Numeric Enums
- String Enums
- Heterogeneous Enums
- Computed and Constant Members
- Reverse Mappings
- Best Practices for Using Enums
- Practical Example: Building a Task Management System
- Common Pitfalls and How to Avoid Them
- Integration with React Applications
- Conclusion
What are TypeScript Enums?
An enum (enumeration) is a special type in TypeScript that allows you to define a set of named constants. They make it easier to document intent or create a set of distinct cases.
Here’s a basic example:
enum Direction {
Up,
Down,
Left,
Right
}
// Using the enum
let playerDirection: Direction = Direction.Up;
Code language: JavaScript (javascript)
Numeric Enums
By default, enums are numeric, starting from 0 and incrementing by 1 for each member:
enum StatusCode {
OK = 200,
NotFound = 404,
InternalServerError = 500
}
console.log(StatusCode.OK); // Outputs: 200
Code language: JavaScript (javascript)
String Enums
TypeScript also supports string enums, which are more readable when debugging:
enum UserRole {
Admin = 'ADMIN',
User = 'USER',
Guest = 'GUEST'
}
const userRole: UserRole = UserRole.Admin;
console.log(userRole); // Outputs: "ADMIN"
Code language: JavaScript (javascript)
Heterogeneous Enums
You can mix string and numeric values in enums, although this is not common practice:
enum BooleanLikeHeterogeneousEnum {
No = 0,
Yes = "YES",
}
Code language: JavaScript (javascript)
Computed and Constant Members
Enum members can have constant or computed values:
enum FileAccess {
// constant members
None = 0,
Read = 1 << 1,
Write = 1 << 2,
ReadWrite = Read | Write,
// computed member
G = "123".length
}
Code language: JavaScript (javascript)
Reverse Mappings
Numeric enums come with reverse mappings, allowing you to get the enum member name from its value:
enum Color {
Red = 1,
Green = 2,
Blue = 3
}
const colorName: string = Color[2]; // Returns "Green"
Code language: JavaScript (javascript)
Best Practices for Using Enums
1. Use Const Enums for Better Performance
When you don’t need reverse mappings, use const enums to generate more optimized code:
const enum Direction {
Up,
Down,
Left,
Right
}
Code language: JavaScript (javascript)
2. Prefer String Enums for Type Safety
String enums are more type-safe and provide better debugging information:
enum ApiEndpoint {
Users = '/api/users',
Posts = '/api/posts',
Comments = '/api/comments'
}
Code language: JavaScript (javascript)
3. Document Complex Enums
Add JSDoc comments to explain the purpose of each enum member:
/** Represents the possible states of a network request */
enum RequestState {
/** Initial state before the request starts */
Idle = 'IDLE',
/** Request is currently in progress */
Loading = 'LOADING',
/** Request completed successfully */
Success = 'SUCCESS',
/** Request failed with an error */
Error = 'ERROR'
}
Code language: PHP (php)
Practical Example: Building a Task Management System
Here’s a practical example combining various enum concepts:
// Define task priority levels
enum TaskPriority {
Low = 'LOW',
Medium = 'MEDIUM',
High = 'HIGH',
Critical = 'CRITICAL'
}
// Define task status
enum TaskStatus {
Todo = 'TODO',
InProgress = 'IN_PROGRESS',
Review = 'REVIEW',
Done = 'DONE'
}
// Task interface using enums
interface Task {
id: number;
title: string;
priority: TaskPriority;
status: TaskStatus;
}
// Example usage
const newTask: Task = {
id: 1,
title: 'Complete TypeScript tutorial',
priority: TaskPriority.High,
status: TaskStatus.InProgress
};
Code language: PHP (php)
Common Pitfalls and How to Avoid Them
1. Avoid Using Number-Based Enums Without Explicit Values
Bad:
enum Status {
Active,
Inactive
}
Good:
enum Status {
Active = 1,
Inactive = 2
}
2. Don’t Mix Types Unless Necessary
Bad:
enum Mixed {
A = 0,
B = 'B',
C = 2
}
Code language: JavaScript (javascript)
Good:
enum Consistent {
A = 'A',
B = 'B',
C = 'C'
}
Code language: JavaScript (javascript)
Integration with React Applications
Enums are particularly useful in React applications for managing component states and props:
enum ButtonVariant {
Primary = 'primary',
Secondary = 'secondary',
Danger = 'danger'
}
interface ButtonProps {
variant: ButtonVariant;
label: string;
}
const Button: React.FC<ButtonProps> = ({ variant, label }) => {
return (
<button className={`btn btn-${variant}`}>
{label}
</button>
);
};
Code language: JavaScript (javascript)
Conclusion
TypeScript enums are a powerful feature that can make your code more maintainable and type-safe. By following the best practices and examples outlined in this guide, you can effectively use enums in your TypeScript projects.
For more advanced TypeScript topics, check out our guide on TypeScript Type Guards or explore TypeScript Abstract Classes.
Start implementing enums in your TypeScript projects today and experience the benefits of more organized and maintainable code.