As a developer working on a project for a US-based company, I recently faced a challenge where I needed to define a set of related constants and use them to create custom types. TypeScript enums proved to be the perfect solution, allowing me to write more readable, maintainable, and type-safe code.
In this tutorial, I will explain how to create custom types from enum values in TypeScript with detailed examples. In this article, we’ll explore how to leverage enums to create custom types and improve your TypeScript development experience.
What are Enums in TypeScript?
Enums allow a developer to define a set of named constants. They provide a way to create a group of related values that can be used throughout your codebase. TypeScript supports both numeric and string-based enums, giving you flexibility in how you define your constants.
Numeric Enums
By default, enums in TypeScript are number-based. Here’s an example of a numeric enum representing the days of the week:
enum Weekday {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}In this case, the enum values start at 0 and increment by 1 for each subsequent value.
String Enums in TypeScript
TypeScript also supports string-based enums, which can be more readable and expressive. Here’s an example of a string enum representing US state codes:
enum StateCode {
California = "CA",
Texas = "TX",
Florida = "FL",
NewYork = "NY"
}String enums provide more meaningful values and can be used directly in string contexts.
Create Custom Types from Enum Values in TypeScript
Now that we understand the basics of enums, let’s explore how to create custom types from enum values. This is particularly useful when you want to define a type that represents a specific set of values.
Using Enum Values as Types
One way to create a custom type from enum values is to use the enum itself as a type directly. TypeScript treats enums as ‘nominal’, meaning you have to use the specific named type. Here’s an example:
enum UserRole {
Admin,
Manager,
Employee
}
function getUserPermissions(role: UserRole) {
// ...
}
getUserPermissions(UserRole.Admin); // Valid
getUserPermissions("Admin"); // Invalid, string literal not allowedIn this example, the UserRole enum is used directly as the type for the role parameter in the getUserPermissions function. This ensures that only valid enum values can be passed as arguments.

Check out: Avoid Duplicate Enum Values in TypeScript
Creating Union Types from Enum Values
Another common approach is to create a union type from the enum values. This allows you to define a type that represents a subset of the enum values. Here’s an example:
enum PaymentMethod {
CreditCard = "CC",
DebitCard = "DC",
PayPal = "PP",
BankTransfer = "BT"
}
type CardPayment = PaymentMethod.CreditCard | PaymentMethod.DebitCard;
function processPayment(method: CardPayment): void {
console.log(`Processing card payment using: ${method}`);
}
processPayment(PaymentMethod.CreditCard); // Allowed
processPayment(PaymentMethod.DebitCard); // Allowed
// Invalid usage (will throw a TypeScript error if uncommented)
// processPayment(PaymentMethod.PayPal); // Error: Not assignable to type 'CardPayment'
The enum groups all payment methods as named constants. The union type restricts allowed values to only “CC” and “DC”. This ensures compile-time safety by preventing invalid values like PayPal. The function processPayment specifically handles only card payments, improving code clarity and correctness.

Check out: Difference Between Undefined and Null In TypeScript
Using Enum Values in Type Assertions in TypeScript
Enum values can also be used in type assertions to narrow down the type of a variable. This is useful when you have a value that you know belongs to a specific enum, but TypeScript doesn’t have that information. Here’s an example:
enum ShippingMethod {
Standard = "STD",
Express = "EXP",
Overnight = "OVN"
}
const method: ShippingMethod = ShippingMethod.Express;
function getShippingCost(method: ShippingMethod) {
console.log(`Calculating cost for shipping method: ${method}`);
}
getShippingCost(method); // Valid, method is of type ShippingMethodThe code prints the shipping method passed to getShippingCost. Since the method is assigned ShippingMethod.Express (“EXP”), the output will show “Calculating cost for shipping method: EXP”. This confirms the function receives a valid enum value and processes it correctly.

Check out: Use TypeScript Enums with Functions
Best Practices and Considerations
When using enums to create custom types in TypeScript, there are a few best practices and considerations to keep in mind:
- Choose between numeric and string enums based on your needs. Numeric enums are default and can be used when the specific values don’t matter. String enums are more readable and can be used directly in string contexts.
- Use descriptive names for your enums and enum values. This improves code readability and makes the intent clear to other developers.
- Be cautious when using enums in external libraries or APIs. Enums are not part of the JavaScript runtime, so they may be unavailable or have different values in external code.
- Consider using const enums for performance and code generation. Const enums are removed during compilation and only their values are used, resulting in smaller bundle sizes.
Conclusion
In this tutorial, we explored how to create custom types from enum values in TypeScript. Enums provide a way to define a set of named constants, and we can leverage them to create more specific and type-safe code. By using enum values directly as types, creating union types from enum values, and utilizing type assertions, we can build more robust and maintainable TypeScript applications.
Remember to choose the appropriate enum type based on your requirements, use descriptive names, and be mindful of external libraries and APIs. With these best practices in mind, you can effectively incorporate enums into your TypeScript projects and take advantage of their benefits.
I hope this tutorial has provided you with a comprehensive understanding of creating custom types from enum values in TypeScript. Happy coding!
You may like to read:
- Loose vs Strict Equality in TypeScript
- Avoid Duplicate Enum Values in TypeScript
- Difference Between Undefined and Null 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.