While working on a TypeScript project, I needed to store values in an object where the keys represented different user roles, such as Admin, Editor, and Viewer.
Instead of using plain strings (which can cause typos or mistakes), I used a TypeScript enum to define the roles. This made the code more readable, safer, and easier to manage.
In this tutorial, I will explain how to use TypeScript enums as object keys. By the end of this article, you will have a deep understanding of TypeScript enums, complete with practical examples and best practices.
What are Enums in TypeScript?
Enums in TypeScript are a way to define a set of named constants. They make it easier to document intent and create a set of distinct cases. Enums can be numeric or string-based. Here’s a quick overview:
Numeric Enums in TypeScript
Numeric enums are the default in TypeScript. They automatically assign numeric values to their members.
enum Status {
Active,
Inactive,
Suspended
}In this example, Status.Active is 0, Status.Inactive is 1, and Status.Suspended is 2.
String Enums in TypeScript
String enums allow you to give meaningful names to values.
enum City {
NewYork = "New York",
LosAngeles = "Los Angeles",
Chicago = "Chicago"
}In this case, City.NewYork is “New York”, City.LosAngeles is “Los Angeles”, and City.Chicago is “Chicago”.
Use TypeScript Enums as Object Keys
Using enums as object keys can be very powerful, especially when you need to map values to a specific set of constants. This is particularly useful in scenarios where you need to ensure that only predefined keys are used in your objects.
Example: Mapping User Roles to Permissions in TypeScript
Let’s consider a real-world example where we need to map user roles to their permissions. This is a common scenario in many applications, particularly in the United States, where user roles and permissions are crucial in various systems.
First, define an enum for user roles:
enum UserRole {
Admin = "Admin",
Editor = "Editor",
Viewer = "Viewer"
}Next, create an object that uses these enum values as keys:
const rolePermissions: { [key in UserRole]: string[] } = {
[UserRole.Admin]: ["create", "edit", "delete", "view"],
[UserRole.Editor]: ["edit", "view"],
[UserRole.Viewer]: ["view"]
};
function logPermissions(role: UserRole): void {
const permissions = rolePermissions[role];
console.log(`Permissions for ${role}: ${permissions.join(", ")}`);
}
logPermissions(UserRole.Admin); // Permissions for Admin: create, edit, delete, view
logPermissions(UserRole.Editor); // Permissions for Editor: edit, view
logPermissions(UserRole.Viewer); // Permissions for Viewer: view
In this example, the rolePermissions object maps each role to an array of permissions. By using enums as keys, we ensure that only valid roles can be used.

Check out: Create Custom Types from Enum Values in TypeScript
Benefits of Using Enums as Object Keys
Using enums as object keys provides several benefits:
- Type Safety: TypeScript ensures that only valid keys are used, reducing the risk of runtime errors.
- Readability: Enums provide meaningful names for values, making the code more readable and maintainable.
- Consistency: Enums help maintain consistency across the codebase by enforcing the use of predefined constants.
Advanced Usage: Dynamic Key Mapping
Sometimes, you may need to generate keys based on enum values dynamically. This can be achieved using TypeScript’s advanced type features.
Example: Dynamic Role-Based Messages in TypeScript
Let’s extend our previous example to include dynamic messages for each role. We’ll create a function that generates a message based on the user’s role.
enum UserRole {
Admin = "Admin",
Editor = "Editor",
Viewer = "Viewer"
}
function getRoleMessage(role: UserRole): string {
const messages: { [key in UserRole]: string } = {
[UserRole.Admin]: "Welcome, Admin! You have full access.",
[UserRole.Editor]: "Welcome, Editor! You can edit content.",
[UserRole.Viewer]: "Welcome, Viewer! You can view content."
};
return messages[role];
}
console.log(getRoleMessage(UserRole.Admin)); // Output: Welcome, Admin! You have full access.
console.log(getRoleMessage(UserRole.Editor)); // Output: Welcome, Editor! You can edit content.
console.log(getRoleMessage(UserRole.Viewer)); // Output: Welcome, Viewer! You can view content.In this example, the getRoleMessage function uses an object with enum keys to return a message for each role. This approach ensures that only valid roles are used and provides clear, readable code.

Check out: Check Enum Equality in TypeScript
Common Pitfalls and Best Practices
While using enums as object keys is powerful, there are some common pitfalls to avoid:
- Avoid Implicit Values: Always define explicit values for your enums to avoid confusion and potential bugs.
- Use String Enums for Readability: String enums are generally more readable and meaningful than numeric enums.
- Leverage TypeScript’s Type System: Use TypeScript’s type system to enforce the use of enums and avoid runtime errors.
Example: Avoiding Implicit Values
enum Status {
Active = 1,
Inactive = 2,
Suspended = 3
}By explicitly defining values, you avoid the risk of unexpected behavior if the order of enum members changes.
Conclusion
Using TypeScript enums as object keys is a powerful technique that can enhance the type safety, readability, and maintainability of your code. By following best practices and avoiding common pitfalls, you can effectively use enums to create robust and reliable applications.
Whether you’re mapping user roles to permissions, generating dynamic messages, or any other use case, enums provide a clear and consistent way to define and use named constants. So, the next time you face a similar challenge, consider using TypeScript enums as object keys to simplify and strengthen your code.
You may like to read:
- Get Enum Key by Value in TypeScript
- Use TypeScript Enums in Classes
- Check if a Value Exists in an Enum in TypeScript
- Get All Enum Values in TypeScript

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.