ES6 symbols is a great fit for enums as they avoid collision. I thouhgt that TS enum
type used Symbols for enums if target:'es6'
, but it doesn't:
enum Role {Employee, Manager, Admin}
let role: Role = Role.Employee;
transpiles to
var Role;
(function (Role) {
Role[Role["Employee"] = 0] = "Employee";
Role[Role["Manager"] = 1] = "Manager";
Role[Role["Admin"] = 2] = "Admin";
})(Role || (Role = {}));
let role = Role.Employee;
any ideas why? With such approach Role.Employee
has the value of 0
, and any other enum with the value of 0
can be used instead of Role.Employee
in runtime?
The they are useless at runtime argument and agree, if at runtime some code tries to change the values of one of your enums, that would not throw an error and your app could start behaving unexpectedly ( that is why Object.
Enums are one of the few features TypeScript has which is not a type-level extension of JavaScript. Enums allow a developer to define a set of named constants. Using enums can make it easier to document intent, or create a set of distinct cases. TypeScript provides both numeric and string-based enums.
As the TypeScript documentation says, even though enums are real objects that exist at runtime, the keyof keyword works differently than you might expect for typical objects. Instead, using keyof typeof will get you a type that represents all enum keys as strings, as we have seen above.
In TypeScript, enums, or enumerated types, are data structures of constant length that hold a set of constant values. Each of these constant values is known as a member of the enum. Enums are useful when setting properties or values that can only be a certain number of possible values.
ES Symbol
is about uniqueness whereas TypeScript enum
is about named constants. Being unique and being constant are two different things.
We can serialize enum
structure as it is essentially just an object. But Symbol
is a different story. You cannot serialize it.
So, when we say constant, we actually mean to use that value as it is which exactly what enum
provides. But Symbol
is not a value that you want to use. It is more like an identity that we wish to make that nobody should be able to clone/replicate.
A constant is something that stays constant. So some code that can run in two different environments, like Node.js and Browser, both will understand the constant value to be same (in simple words, the developer is creating a value for constant, ex. string or number). But for Symbol
, imagine it to not have any notion of value. If we attempt to use it as value, then it means it is two separate things (because the runtime is creating those Symbol
values, not developer).
In the same light, if you have used redux, we prefer string
over Symbol
to represent our action.
Further, in case of TypeScript, enum
can also be used as ambient
or substitution
value. In this case, it is the only compiler for whom the enum value matters. During compilation, type erasure
may remove enum
reference altogether. Now, this is something you cannot do with Symbol. Creation of Symbol
is runtime only activity. So if we use Symbol
for enum
, then we lose to the ability of enum
to be compile-time only feature.
Thus not using Symbol
for enum
seems a sensible choice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With