参考官方文档:https://www.tslang.cn/docs/handbook/enums.html
理解:枚举是列举固定几个值,直接定义变量的话的话可以随意定义,枚举只能使用你定义好的几个值,枚举是个类,定义的值是基本类型,类能有更多操作
例如你定义一个方法接收一个参数,这个参数如果是int型,别人在调用你这个方法时可以传1或2等任意数字,虽然你告诉了同事,只能传0或1,
如果你把参数定义成只能传某个类型,例如是个枚举类,那么别人只能传你枚举类里定义好的几个类型,传其它的就会在编译时期报错
我们定义了一个数字枚举, Up
使用初始化为 1
。 其余的成员会从 1
开始自动增长。 换句话说,Direction.Up
的值为 1
, Down
为 2
, Left
为 3
, Right
为 4
。
enum Direction { Up = 1, Down, Left, Right }
我们还可以完全不使用初始化器:现在, Up
的值为 0
, Down
的值为 1
等等。 当我们不在乎成员的值的时候,这种自增长的行为是很有用处的,但是要注意每个枚举成员的值都是不同的。
enum Direction { Up, Down, Left, Right, }
通过枚举的属性来访问枚举成员,和枚举的名字来访问枚举类型:
enum Response {
No = 0,
Yes = 1,
}
function respond(recipient: string, message: Response): void {
// ...
}
respond("Princess Caroline", Response.Yes)
不带初始化器的枚举或者被放在第一的位置,或者被放在使用了数字常量或其它常量初始化了的枚举后面。 换句话说,下面的情况是不被允许的
enum E {
A = getSomeValue(),
B, // error! 'A' is not constant-initialized, so 'B' needs an initializer
}
/*由于getSomeValue()不是一个初始常量(到运行时才能确定的值就不是constant值了),所以此时需要给B初始值*/
在一个字符串枚举里,每个成员都必须用字符串字面量,或另外一个字符串枚举成员进行初始化。
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
// 以下所有枚举成员都是常量
enum E { X }
enum E1 { X, Y, Z }
enum E2 {
A = 1, B, C
}
enum FileAccess {
None,
Read = 1 << 1,
Write = 1 << 2,
ReadWrite = Read | Write,
// computed member
G = "123".length
}
当枚举成员成为了类型
enum ShapeKind {
Circle,
Square,
}
interface Circle {
kind: ShapeKind.Circle;
radius: number;
}
interface Square {
kind: ShapeKind.Square;
sideLength: number;
}
let c: Circle = {
kind: ShapeKind.Square,
// ~~~~~~~~~~~~~~~~ Error!
radius: 100,
}
当枚举类型本身变成了每个枚举成员的 联合
下面这个例子里,我们先检查 x
是否不是 E.Foo
。 如果通过了这个检查,然后 ||
会发生短路效果, if
语句体里的内容会被执行。 然而,这个检查没有通过,那么 x
则 只能为 E.Foo
,因此没理由再去检查它是否为 E.Bar
。
enum E {
Foo,
Bar,
}
function f(x: E) {
if (x !== E.Foo || x !== E.Bar) {
// ~~~~~~~~~~~
// Error! Operator '!==' cannot be applied to types 'E.Foo' and 'E.Bar'.
}
}
enum Enum {
A
}
let a = Enum.A;
let nameOfA = Enum[a]; // "A"
// 例如打印下Role 看看解雇
enum Role {
Reporter = 1,
Developer,
Maintainer,
Owner,
Guest
}
外部枚举用来描述已经存在的枚举类型的形状。
declare enum Enum {
A = 1,
B,
C = 2
}
外部枚举和非外部枚举之间有一个重要的区别,在正常的枚举里,没有初始化方法的成员被当成常数成员。 对于非常数的外部枚举而言,没有初始化方法时被当做需要经过计算的。
1.成员不初始化的话,默认是从0开始自增
enum Enum {A,B,C }
console.log(Enum); // {0: "A",1: "B",2: "C",A: 0,B: 1,C: 2}
2.数字型的枚举可以映射,字符串类型的枚举是不可以映射的.
enum Enum {A,B}
enum Strs {A = 'apple',B = 'orange'}
console.log(Enum); // {0: "A",1: "B",A: 0,B: 1}
console.log(Strs ); // {A: "apple"B: "orange"}
3.第一个成员初始化赋值为3的话,后面的成员从3开始增长
enum Enum {A = 3,B,C}
console.log(Enum); // {3: 'A',4: 'B',5:'C', A: 3,B: 4,C: 5}
4.如果第n个成员初始化赋值为string类型,则n后面的成员要给初始值
enum Enum {A,B='apple',C}; // 此时C不初始化会报错 Enum member must have initializer
5.不建议数字枚举和字符串枚举混用
enum Enum {A,B='apple',C}; 这种是不建议的
6.常量枚举成员在编译阶段会被计算出结果,计算类枚举成员的值会被保留,只有到运行时才会被计算
7.const声明的枚举是常量枚举,会在编译阶段被移出,意味着编译后没有任何代码的
当不需要对象,但需要一个对象的值的时候使用常量枚举
const enum Month { Jan, Feb, Mar, Apr }
let month = [Month.Jan, Month.Feb, Month.Mar];
// 编译的结果Month 是没有产生任何代码的
var month = [0 /* Jan */, 1 /* Feb */, 2 /* Mar */];
8.枚举类型:
①.所有成员没有初始值 enum E { a, b }
②.所有成员初始值为数字 enum F { a = 0, b = 1 }
③.所有成员初始值为字符串 enum G { a = 'apple', b = 'banana' }
let e: E = 3, f: F = 4;
let e1: E.a = 3, e2: E.b = 3, e3: E.a = 4;
由于E和F是纯数字,所以可以把任意的number赋值给e和f.取值也可以超出枚举值 let e: E = 3 或 let e: E = E.a ;
let g1:G = G.a, g2:G.b = G.b
G的成员是字符串,只能是枚举成员的类型复制给g1和g2
两种不同的枚举值是不可以比较的
e === f // 报错:因为类型“E”和“F”没有重叠,所以只会返回false
e1 === e2 // 报错 ...
e1 === e3 // 正确
g1 === g2 // 报错 ,因为“E.a”和“E.b”类型没有重叠,所以只会返回false