Enums with Typescript - why it's bad? Possible solutions
Have you ever been told to avoid using enums in TypeScript, but weren't sure why? While they can be useful for defining constant values, enums can actually be quite dangerous. This article will explore the potential problems with enums and suggest safer and more reliable alternatives.
The problem with code generated by enums
One reason to avoid using enums is the extra code they generate at compile time. This can increase the size of the final file and negatively affect the loading speed and performance of the application. Even using constant enums instead of regular enums may not completely solve this problem. This is something to consider, especially if files are shared between the frontend and backend of an application.
The issue with numeric types
Another problem with regular numeric enums that do not set string values is that they are not type-safe. This means that a function that takes user roles can accept any numeric value, which can cause security and performance problems. For example, a user with a numeric value of 10 could potentially access a role they shouldn't be able to.
The problem with named types
Enums are a named type, meaning they only accept certain values and cannot be passed to functions or objects that expect a string enumeration. This can lead to compatibility issues and requires careful consideration when using and designing enums.
First solution - assign values to enum
In this solution, we can assign string values to the enum, such as producer
and consumer
. This allows us to make our code more predictable and robust. We can also avoid the flexibility problem where passing a string value to the function would not work. The visible()
function takes an argument of type Roles
, which is the enumeration we defined. We can pass a value of Roles.Producer
to the function, and it will return true
. However, if we try to pass a value of 10
, which is not an option in the enum, we will get an error. This error prevents us from passing invalid data, which can help us catch potential bugs early. Similarly, if we try to pass a string value like consumer
, the function will return false
because consumer
is not an option in the enum - this is not really an elastic approach.
Second solution - use object instead
Using an object with string values allows for more flexibility than enums because values can be added or removed at runtime without generating additional code. In addition, the use of the "as const" assertion ensures that the values are treated as string literals, providing type safety. However, it's worth noting that this solution may not be suitable for all use cases, especially when the number of values is very large.