TypeScript Enum vs ES6 Symbol

· 3 min read

JavaScript’s primitive data types added the Symbol type when ES6 arrived, and ES6 (ES2015) was released 5.5 years ago.

However, in actual development, I haven’t used Symbol much because in the TypeScript environment, I seem to consider it even less since TypeScript has enum types. But after serious study and research, I realize this understanding was wrong.

Here I’ll mark down the differences between the two to clarify their distinctions and meanings for healthier and more reasonable usage.

TypeScript Enum

First, TypeScript is just an intermediate language, a development language, and TypeScript ultimately needs to be compiled to JavaScript, so this type itself is just a wrapper.

For example, if we define an enum like this:

enum Config {
  CSV,
  JSON
}

After TSC compilation, we can see it becomes:

var Config;
(function (Config) {
    Config[Config["CSV"] = 0] = "CSV";
    Config[Config["JSON"] = 1] = "JSON";
})(Config || (Config = {}));

Looking at TypeScript’s official description of Enum:

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.

Therefore, we can conclude:

  1. TypeScript enums are used for defining sets of constants
  2. Since TypeScript enums are just utility types, they compile down to JavaScript objects

ES6 Symbol

Symbol is a new data type added in ES6, designed to represent unique identifiers for object properties and prevent property conflicts.

Here’s the official description from MDN:

The data type symbol is a primitive data type. The Symbol() function returns a value of type symbol, has static properties that expose several members of built-in objects, has static methods that expose the global symbol registry, and resembles a built-in object class, but is incomplete as a constructor because it does not support the syntax “new Symbol()”.

Every symbol value returned from Symbol() is unique. A symbol value may be used as an identifier for object properties; this is the data type’s primary purpose, although other use-cases exist, such as enabling opaque data types, or serving as an implementation-supported unique identifier in general. Some further explanation about purpose and usage can be found in the glossary entry for Symbol.

Therefore, we can conclude:

  1. Symbol values are unique, even Symbol('hey') === Symbol('hey') returns false
  2. Symbol can be used to represent private properties, so methods like JSON serialization and Object.keys cannot access these properties.

Conclusion

The above introduction is crucial but also rough. For usage, it still comes down to one phrase: use what’s appropriate. For example, if object properties are only used on the frontend and just need unique identification, then Symbol is very suitable. If they also need to be serialized and transmitted to the backend, then enums are more appropriate.

Done!