The Pitfalls of Using Enums in TypeScript
Exploring the Downsides: When to Avoid Enums in TypeScript
enum
is a type which has defined set of values, that can be either numeric or string .
Key things to note about enums
:
1. If members of enum
are not initialised, then by default first member will be assigned 0
and every other member get a value increment by previous memeber.
2. If we initialize one member, then we have to give initial value to all other members, otherwise typescript will throw error.
3. We can club string
and numeric
initialiser in same enum, once we give a numeric value, all other members will get a value automatically, incremented by 1.
What is the problems with enums?
enum
in typescript works differently as compared to other typescript types.
1. No type
check if enum
members are initialised with numeric
values
Note: This has been fixed in TypeScript version ≥ 5.0.4
Solution for the problem:
We can solve the problem of not throwing error when random numbers are used, by using string
initialisers instead of numeric
ones.
But using also has downside, let’s see the downside in below point.
2. enums are does not follow structural concept of typescript
In typescript we two shapes shares same structure then they are considered to be same, but thats not the case with enums
But, that’s not true with enums
, even if we pass same string
it will throw error
in above code, even though we are passing same string
, still we are getting error message. to fix this we have to enum
members.
In real world application we have to take input from user, in that case even if we pass the same string it won’t work.
In that case it is advised to not use enums
, instead we can use Object
and as const
to achieve the same functionality.
Here we are indexing through the object, and extracting out the values of object, into an union type.
Now you will think why don’t we simply use a type
union with strings.
type Ramayan = "ram" | "sita" | "laxman";
We can definitely use this one instead of using the complex keyof
typeof
solution, but the trade of will be, that we’ll be missing out the autocomplete suggestion that we get in Objects.
3. unlike other types in typescript, enum
can be used in runtime like a normal JS variable.
Typescript is a compile time thing, once we generate the build and run the application in the browser then all the type
information is stripped away and we only get plain javascript.
see below example, where we are trying to pass a interface
as an parameter in a function and getting error immediatley.
But that’s not the case with enum
, when we create a enum
we also get JS version of it, and once build is generated all the information is getting included in the plain javascript code. and the is the reason in below code I am able to pass a enum
as an argument.
4. JS version of enums are different in case of string and numeric members
Here is the Javascript version of a enum.
Now if we try to get values of this enum in JS, then the member
name is also get appended with values.
But that’s not the case with string
members, we only get values for all string
5. no warning/error on duplicated initialisers for member.
We have to use additional rule to enable a check around such usage.
6. No warning/error on using dynamic initialiser which changes the value of member
Typescript won’t throw any error in such case, now with large and increasing code base such code might create unwanted behavior and might become hard to debug.
Due to all these weired behavior of enums, it is advised to stay away from it. But if you know how they works and like them to use go ahead and use them it’s completely fine to use. But do not forget its consequences.
Thanks for Reading. 👏 I am available in topmate for any of your requirements related to WebDevlopment.