“This is the 12th day of my participation in the August Text Challenge.
TypeScript adds enumerations to ES to make it possible to give names to sets of values in TypeScript, which is developer-friendly to understand that enumerations are dictionaries. Enum types are defined using enum:
enum Day {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY
}
Copy the code
The enumerated type Day defined above has seven values, and TypeScript assigns numbers to each of them, starting at 0 by default. When used, names can be used without remembering the relationship between numbers and names:
enum Day {
SUNDAY = 0,
MONDAY = 1,
TUESDAY = 2,
WEDNESDAY = 3,
THURSDAY = 4,
FRIDAY = 5,
SATURDAY = 6
}
Copy the code
Here is what the above code looks like when translated into JavaScript:
var Day = void 0;
(function (Day) {
Day[Day["SUNDAY"] = 0] = "SUNDAY";
Day[Day["MONDAY"] = 1] = "MONDAY";
Day[Day["TUESDAY"] = 2] = "TUESDAY";
Day[Day["WEDNESDAY"] = 3] = "WEDNESDAY";
Day[Day["THURSDAY"] = 4] = "THURSDAY";
Day[Day["FRIDAY"] = 5] = "FRIDAY";
Day[Day["SATURDAY"] = 6] = "SATURDAY";
})(Day || (Day = {}));
Copy the code
As you can see, each value is assigned a corresponding number.
In TypeScript, we need to get members of an enumerated collection as points:
console.log(Day.SUNDAY) / / 0
console.log(Day.MONDAY) / / 1
Copy the code
With the basic use of enumerations out of the way, let’s take a look at common enumerations.
1. Enumeration of numbers
In the above example, you define a set of numbers that starts at 0 by default, called a numeric enumeration, by specifying only constant names. If you want to increment from another value, you can specify the index of the first value:
enum Color {
Red = 2,
Blue,
Yellow
}
console.log(Color.Red, Color.Blue, Color.Yellow); / / 2, 3, 4
Copy the code
If you can specify an index value for a field, all fields that do not have an index value will be incremented by one:
// Specify some fields, others use default increment indexes
enum Status {
Ok = 200,
Created,
Accepted,
BadRequest = 400,
Unauthorized
}
console.log(Status.Created, Status.Accepted, Status.Unauthorized); / / 201 202 401
Copy the code
In addition, it is possible to assign each field an arbitrary index value that is not contiguous:
enum Status {
Success = 200,
NotFound = 404.Error = 500
}
console.log(Status.Success, Status.NotFound, Status.Error); / / 200 404 500
Copy the code
Numeric enumerations can use computed values and constants when defining values. Note, however, that if a field uses a calculated value or constant, then the field immediately following that field must be set to its initial value. The default increment value cannot be used here.
// The initial value is calculated
const getValue = () = > {
return 0;
};
enum ErrorIndex {
a = getValue(),
b, // The error enumerator must have an initialized value
c
}
enum RightIndex {
a = getValue(),
b = 1,
c
}
// The initial value is constant
const Start = 1;
enum Index {
a = Start,
b, // The error enumerator must have an initialized value
c
}
Copy the code
2. Enumeration of strings
TypeScript calls enumerations that define values as string literals string enumerations require that each field’s value be either a string literal or another string enumerator of that enumerated value:
// Use string literals
enum Message {
Error = "Sorry, error",
Success = "Hoho, success"
}
console.log(Message.Error); // 'Sorry, error'
// Use other enumerators in enumeration values
enum Message {
Error = "error message",
ServerError = Error,
ClientError = Error
}
console.log(Message.Error); // 'error message'
console.log(Message.ServerError); // 'error message'
Copy the code
Note that other enumerators here refer to enumerators in the same enumeration value, because string enumerations cannot use constants or computed values, so members in other enumerations cannot be used.
3. Reverse mapping
When you define an enumeration value, you can obtain the corresponding value in the form of Enum[‘key’] or Enum. Key. TypeScript also supports reverse mapping, but only numeric enumerations, not string enumerations. Consider the following example:
enum Status {
Success = 200,
NotFound = 404.Error = 500
}
console.log(Status["Success"]); / / 200
console.log(Status[200]); // 'Success'
console.log(Status[Status["Success"]]); // 'Success'
Copy the code
Enumerations defined in TypeScript are actually an object when compiled. In the generated code, enumerations are compiled into an object that contains both a forward mapping (name -> value) and a reverse mapping (value -> name). Let’s see what Status looks like when compiled in the code above:
{
200: "Success".404: "NotFound".500: "Error".Error: 500.NotFound: 404.Success: 200
}
Copy the code
As you can see, TypeScript adds the field name of the enumerated value as the property name and the property value of the object, and the field value of the enumerated value as the property name and name of the object. This can be done either by enumerating the value’s field name or by enumerating the value’s value to the field name.
4. Heterogeneous enumeration
Heterogeneous enumeration is an enumeration value whose member values have both numeric and string types, as follows:
enum Result {
Faild = 0,
Success = "Success"
}
Copy the code
Asynchronous enumerations are not recommended during development. Because when a class of values is organized into an enumerated value, they tend to have similar characteristics. For example, when doing interface request, the return status code, if the status code is numeric, if it is a prompt message, are strings, so in the use of enumeration, often can avoid the use of heterogeneous enumeration, mainly to do a good job of sorting out the type.
5. Constant enumeration
In TypeScript, after enumeration values are defined, the compiled JavaScript code creates a corresponding object that can be used at runtime. But what if you use enumerations just to make your program readable and don’t need the compiled object? This will increase the amount of compiled code. In TypeScript, we have a const enum. We use the const keyword before the statement defining the enumeration. This way the compiled code does not create the object, but replaces it with the corresponding value from the enumeration:
enum Status {
Off,
On
}
const enum Animal {
Dog,
Cat
}
const status = Status.On;
const animal = Animal.Dog;
Copy the code
When compiled into JavaScript, the code above looks like this:
var Status;
(function(Status) {
Status[(Status["Off"] = 0)] = "Off";
Status[(Status["On"] = 1)] = "On";
})(Status || (Status = {}));
var status = Status.On;
var animal = 0; // Dog
Copy the code
Status[” Off “] = 0 sets the Off attribute to the Status object, and the value is set to 0. This assignment expression returns the value on the right-hand side of the equals sign, which is 0, so Status[Status[“Off”] = 0] = “Off” equals Status[0] = “Off”. After the object is created, assign the value of Status’s On property to Status; Instead of creating an animal object like Status, the compiled code replaces the value 0 for animal. Dog with the animal. Dog position of the const animal = animal. Dog expression.
By defining constant enumerations, you can maintain an associated set of constants in a clear, structured form. And because the definition and inline member values are erased after translation, the code is no worse in terms of size and performance than the directly inline constant values.
6. Enumerator and joint enumerator types
If all the members of an enumeration value are literal-type values, then each member of the enumeration and the enumeration value itself can be used as a type. We call such enumerators literal enumerators. There are three types of values that satisfy the criteria for an enumerator:
- An enumerator with no initial value, for example:
enum E { A }
- The value is a string literal, for example:
enum E { A = 'a' }
- Values are numeric literals or with
-
A numeric literal of a symbol, for example:enum E { A = 1 }
,enum E { A = -1 }
(1) Enumerator type
An enumerator becomes a type when all enumerators have literal enumerations:
enum Animal {
Dog = 1,
Cat = 2
}
interface Dog {
type: Animal.Dog;
}
interface Cat {
type: Animal.Cat;
}
let cat: Cat = {
type: Animal.Dog // error [ts] Cannot assign type 'animal. Dog' to type 'animal. Cat'
};
let dog: Dog = {
type: Animal.Dog
};
Copy the code
As you can see, line 7 of the code uses animal. Dog as the type, specifying that the interface Dog must have a type field with type animal. Dog.
(2)Joint enumerated type
When an enumeration value meets the criteria, the enumeration value can be treated as a union type containing all members:
enum Status {
Off,
On
}
interface Light {
status: Status;
}
enum Animal {
Dog = 1,
Cat = 2
}
const light1: Light = {
status: Animal.Dog // Error cannot assign type 'animal. Dog' to type 'Status'
};
const light2: Light = {
status: Status.Off
};
const light3: Light = {
status: Status.On
};
Copy the code
The above example defines the type of the status field of the interface Light as the enumeration value status, then the attribute value of status must be either status. Off or status. On, which is equivalent to status: Status. Off | Status. On.
7. Enumeration merge
With common enumeration types out of the way, let’s finally look at the concept of enumeration merging. For values of enumerated types, we can declare them separately:
enum Day {
SUNDAY,
MONDAY,
TUESDAY
}
enum Day {
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY
}
Copy the code
TypeScript then merges the enumerated value and compiles it to JavaScript as follows:
var Day = void 0;
(function (Day) {
Day[Day["SUNDAY"] = 0] = "SUNDAY";
Day[Day["MONDAY"] = 1] = "MONDAY";
Day[Day["TUESDAY"] = 2] = "TUESDAY";
Day[Day["WEDNESDAY"] = 3] = "WEDNESDAY";
Day[Day["THURSDAY"] = 4] = "THURSDAY";
Day[Day["FRIDAY"] = 5] = "FRIDAY";
Day[Day["SATURDAY"] = 6] = "SATURDAY";
})(Day || (Day = {}));
Copy the code