preface

Maybe the folks at the front end will ask if JavaScript hasn’t had an enumerated type since its birth, and we’re all doing just fine. Why does TypeScript introduce enumerated types? Backend students who are forced to write front ends may ask, are TypeScript enumerations the same as Java/.NET? Let’s discuss and try to answer it together.

Front ends need enumerations all the time

I’m sure everyone on the front end can tell you with absolute certainty that we’ve never written enumerations. That’s because although ECMAScript includes enum as a reserved word, as of ES2020 there is no implementation specification for enumerations. Just because a language doesn’t provide specifications and language implementations doesn’t mean that programmers who are active and brave enough to build wheels won’t be able to do it themselves. If the language doesn’t provide one, and we’re so determined to make one ourselves, what exactly is enumeration going to solve for us?

Enumerations are really useful

First, enumeration literally means traversing all the members of a finite set of several values. There are two key points:

  1. Finite set;
  2. Traverse.

That is, as long as we need to indicate that the value of a variable must be a member of some finite set, we can’t get around enumeration.

Write a JavaScript version of the enumeration

Here is an enumeration implementation that just meets most business requirements:

Class Color {// tricky: Static Red = new Color('Red') static Green = new Color('Green') // Reverse mapping static counter = null valueOf(value) { for (var name in Color) { if (! (name in Color.prototype) && Color[name].value === value) { return Color[name] } } } constructor(name, value){ if ('counter' in Color); else return this.name = name if (value == null) { if (Color.counter === null) { this.value = Color.counter = 0 } else { this.value = ++Color.counter } } else { this.value = Color.counter = value } } toString() { return `Color.${this.name}` }} delete color.counter object.freeze (Color) // Tricky: Prevents the enumerator from being modified outside the definitionCopy the code

In fact, we just want to express that some variables will be the Color of a finite set of Red and Green members as the value, but we need to write so much semantically irrelevant code (strictly follow the “can write hi, never write Hello” principle). And in average-sized projects, where there is often more than one enumerated type, copy-and-paste can be a real solution, but it’s not really elegant. The language implementation of TypeScript’s built-in enumerations solves this problem.

TypeScript enumerations are really different from the backend

Enumerations will be familiar to anyone on the back end (unless you’re on the Pyton/Nodejs back end). TypeScript is a superset of JavaScript, but ultimately needs to be compiled into JavaScript code that is compatible with existing JavaScript libraries. So it’s not exactly the same as the enumeration type on the back end. So I recommend that you use the empty cup mentality and focus on understanding TypeScript enumerations, using past knowledge as an accelerator rather than a fence.

Numeric enumeration types and string enumeration types

Enumerated types are covered in detail in the TypeScript tutorial, but I think it’s important to understand that they fall into two main categories:

  1. Numeric enumeration type
Enum Response {No = 0, // Manually set initializer Yes = // Attach default initializer to support automatic growth, so Yes = 1}Copy the code

Features are: 1.1. Enumerators come with default initializers; 1.2. Initializer supports automatic growth; 1.3. Reverse mapping is supported. (Note: this is reverse mapping, not value conversion to enumerator)

  1. String enumeration type
enum Color {
  Red = 'Red',
  Green = 'Green',
}
Copy the code

The properties are: 1.1. Initializers must be set for enumerators; 1.2. Initializer does not support automatic growth; 1.3. Reverse mapping is not supported.

The calculation and constant members are just subdivisions of the initializers of the two enumerated types.

enumReverse mapping of numeric enumeration types is possible

The previous section explained that numeric enumeration types support reverse mapping, but only if they are defined through enums. That’s because enum Respose {No,Yes,} will eventually compile to JavaScript code like this:

var Response;
(function (Response) {
    Response[Response["No"] = 0] = "No";
    Response[Response["Yes"] = 1] = "Yes";
})(Response || (Response = {}));
Copy the code

Then we can get “No” by reverse mapping Response[0]. Enum Color {Red=’Red’,Green=’Green’,

var Color;
(function (Color) {
    Color["Red"] = "Red";
    Color["Green"] = "Green";
})(Color || (Color = {}));
Copy the code

Can only say very unpretentious, so there is no what to say, we pay attention to the difference in the use of good.

const enumEfficient compile time inlining

The official documentation explicitly states that “in most cases, enumerations are a very efficient solution. In some cases, however, the requirements are strict. To avoid the overhead in extra generated code and extra indirect access to enumerators, we can use const enumerations. “Why? That’s because compile-time enumerated types defined by const enum have the same effect as constants defined by C/C++ #define. To put it bluntly, if an enumeration type is defined through a const enum and nothing else is called, the code will be erased at compile time. When the enumeration type is called elsewhere, the value of the enumeration type member is directly inlined to use, as follows:

const enum Response {
    No,
    Yes,
}

console.log(Response.NO, Response.Yes)
Copy the code

Console. log(0, 1) will only perform better than enum.

When to use itenum? And in what contextconst enum?

First, the conclusion:

  1. useenumScenario:

1.1. Reverse mapping is required; 1.2. The compiled JavaScript code needs to preserve objects. Property or object [property] form. 2. Const enum: Const enum can be used without enum.

The first of the enum scenarios is fairly understandable, but what about the second? Here’s an example of what actually happened to give you a better idea: * Background: * Writing type declarations for Photoshop’s ExtendScript. Requirement: DialogModes.NO return value in ExtendScript is DialogModes.NO itself, the code form of DialogModes must be preserved in compiled JavaScript.

So why encourage people to use const enum when they can use const enum? This is TypeScript’s compile-time optimization for you. Why not use a good thing? Isn’t compile-time optimization sweet?

External enumerationdeclare enumThe role of?

External enumerations are even the enumerated type declarations we are forced to write for libraries already written in JavaScript to make better use of them in the TypeScript development environment. Such as ExtendScript standard inventory in enumeration DialogModes.NO, DialogModes.YES, DialogModes. Write the following external enumeration type declarations in the.d.ts file

declare enum DialogModes {
    NO,
    YES,
    ALL,
}
Copy the code

conclusion

We don’t get around enumerations in our daily development. TypeScript provides language implementation and compile-time optimizations that protect us from thinning hair as we think about how to optimize enumerations and greatly reduce the risk of a copy-and-paste code base growing in size. Write less code, do the right thing, and leave work earlier

Reprint please indicate the from: www.cnblogs.com/fsjohnhuang… — ^_^ fat boy John