As far as JS is concerned, enumerations are not a pure type; they invade the JS runtime.
Digital Numeric enums
The default name is 1 and age is 2. Use when it is time to read directly.
Enum Num {name, age} // name is 0 const name = NumCopy the code
You can also specify any number
enum Num {
name = 0,
age = 3
}
Copy the code
Since the increase
Numeric enumeration type that is incremented by 1 whenever the value of the first property is specified.
enum Num{
first = 10,
second
}
Copy the code
The value is String enums
During debugging, the Number enums are only simple numbers and therefore have no semantics. Strings have semantics.
enum Str {
up = "UP",
down = "DOWN"
}
Copy the code
Heterogeneous enumeration Heterogeneous enums
It’s best not to write it this way.
enum BooleanLikeHeterogeneousEnum { No = 0, Yes = "YES",}
Copy the code
Computes with constant members Computed and constant members
If the expression of an enumerator is a subtype of a TS expression, its value can be fully evaluated at TS compilation time.
Recommended enumerator expressions are as follows:
1. Literal members: numbers or strings
2. References to constant members can come from other enumeration types
3. Bracketed enumerator expressions
4. Expressions containing one of the unary operators +, -, ~
5. 2 hospital operator, +, -, *, /, %, < <, > >, > > >, &, |, ^
6. Error when using NaN or Infinity
Enum FileAccess {/ / constant None, Read = 1 < < 1, the Write = 1 < < 2, ReadWrite = Read | Write, / / calculated value G = 123 length}Copy the code
Associative enumerations with enumerator types
Literal enumerators are not computable.
When a literal enumerator has no initial value, or its initial value is a string, or a number, or a numeric literal with a unary operator, the member is considered a constant enumerator.
Edge cases
An error occurs when an enumerator is used in both a type and a value.
enum ShapeKind {
Circle,
Square
}
interface Circle {
kind: ShapeKind.Circle;
radius: number
}
interface Square {
kind: ShapeKind.Square;
sideLength: number
}
// crash
let c:Circle = {
// Type 'ShapeKind.Square' is not assignable to type 'ShapeKind.Circle'.
kind: ShapeKind.Square,
radius: 100
}
Copy the code
An enumeration type becomes a collection of each enumeration member. So the type system knows every value in an enumerated type. The result is an error message when comparing values of enumerated types.
enum E { Foo, Bar } function f(x: E){ if(x ! == E.Foo || x ! == E.Bar){ // This condition will always return 'true' since the types 'E.Foo' and 'E.Bar' have no overlap. } }Copy the code
Enumeration types at run time
In the JS runtime, enumerations are real objects.
Enumeration types at compile time
You can use keyof Typeof to get all keys in an enumeration type
enum LogLevel{
ERROR,
WARN,
INFO,
DEBUG
}
// 'ERROR' | 'WARN' | 'INFO' | 'DEBUG'
type LogLevelStrings = keyof typeof LogLevel
Copy the code
Reverse mappings
Numeric enumerators need to create reverse mapping, which is a mapping of enumeration values –> keys.
enum Enum{
A
}
let a = Enum.A
// A
let nameOfA = Enum[a]
Copy the code
Compiled into JS
'use strict' var Enum; (function (Enum) {/ / here made A value (0) -- - > the key mapping Enum [Enum [" A "] = 0] = "A"}) (Enum | | (Enum = {})) let A = Enum. Let A nameOfA = Enum[a]Copy the code
This operation is not required for string members.
Enum enum {A = "string"} let nameOfA = enum [A]Copy the code
Compiled into JS
var Enum
(function (Enum){
Enum["A"] = "string";
})(Enum || (Enum = {}))
var a = Enum.A
var nameOfA = Enum[a]
Copy the code
const enums
By using const, you avoid unnecessary calls that generate extra code and values that are unnecessary.
const enum Enum{
A = 1,
B = A * 2
}
Copy the code
Const emuns can only use constant enumeration expressions. Enumeration-related code can be removed completely after compilation.
const enum Direction { Up, Down, Left, Right,}let directions = [ Direction.Up, Direction.Down, Direction.Left, Direction.Right,]; /** @format */var Direction; (function (Direction) { Direction[Direction["Up"] = 0] = "Up"; Direction[Direction["Down"] = 1] = "Down"; Direction[Direction["Left"] = 2] = "Left"; Direction[Direction["Right"] = 3] = "Right"; })(Direction || (Direction = {})); var directions = [ 0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */,]; //# sourceMappingURL=index.js.mapCopy the code
Of course, this effect cannot be achieved with calculated members.
Right in the bottom
/** @format */enum Enum{ A}const enum Direction { Up, Down, Left = Enum.A, Right = "123".length,}let directions = [ Direction.Up, Direction.Down, Direction.Left, Direction.Right,]; /** @format */var Enum; (function (Enum) { Enum[Enum["A"] = 0] = "A"; })(Enum || (Enum = {})); var Direction; (function (Direction) { Direction[Direction["Up"] = 0] = "Up"; Direction[Direction["Down"] = 1] = "Down"; Direction[Direction["Left"] = 0] = "Left"; Direction[Direction["Right"] = "123".length] = "Right"; })(Direction || (Direction = {})); var directions = [ 0 /* Up */, 1 /* Down */, 0 /* Left */, Direction.Right,]; //# sourceMappingURL=index.js.mapCopy the code
Ambient enums
Declares an enumeration that can be used to describe the shape of an existing enumeration.
delcare enum Enum{
A = 1,
B,
C = 2
}
Copy the code
The difference between non-ambient and ambient enumerations is that an ordinary enumerator with no initial value is constant if the value of its previous enumerator is constant. An ambient with no initial value, an inordinate number of enumerators with no initial value, is always considered a calculated value.
That is, it does not get killed like const enums.
declare enum
declare enum Gender { Female, Male}console.log(Gender.Female)
Copy the code
The generated JS
The runtime reported an error because the Gender variable was not present, cheating TS
console.log(Gender.Female); //# sourceMappingURL=index.js.mapCopy the code
declare const enum
declare const enum Gender { Female, Male}console.log(Gender.Female)
Copy the code
The generated JS
console.log(0 /* Female */); //# sourceMappingURL=index.js.mapCopy the code
Objects and enumerations
Objects inferred to be const can be used instead of enumerations
const enum EDirection { Up, Down } const ODirection = { Up: 0, Down: 1 } as const // (enum member) EDirection.Up = 0 EDirection.Up // (property) Up: 0 odirection. Up // function walk(dir: Typeof ODirection = typeof ODirection[keyof typeof ODirection] function run(dir: typeof ODirection){} Direction){} walk(EDirection.Left) run(ODirection.Right)Copy the code
Advantages of enumerations
keep codebase aligned with state of JavaScript and when/if enums are added to JavaScript then you can move to the additional syntax
reference
www.typescriptlang.org/docs/handbo…
zhuanlan.zhihu.com/p/125889229