枚举
前两天写数据类型的时候有简单介绍过枚举类型,这篇将会更加详尽的列举不同场景枚举的使用
数字枚举
例如在查询订单状态时经常会返回状态码0、1、2、3,分别对应已支付、未支付、订单取消、申请售后;对新接手的人完全一头雾水,使用数字枚举进行命名,更加清晰;
enum OrderType {
finish,
notPay,
cancel,
afterSales
}
如上,我们定义了一个数字枚举, 默认序列为0起始,或者按需初始化成员的值
enum OrderType {
finish = 200,
notPay = 300,
cancel = 500,
afterSales = 400
}
这两个例子都是使用的常量去定义的枚举项的值,也可以是某个方法的返回值
function getSth(){return 200}
enum OrderType {
finish = getSth(),
notPay = 300,
cancel = 500,
afterSales = 400
}
需要注意的是不带常量的的项后边如果没有赋值会引起错误
enum OrderType {
finish = getSth(),
notPay //error
}
enum OrderType {
finish = getSth(),
notPay = 300,
cancel //fine
}
字符串枚举
字符串枚举指每个成员都必须用字符串字面量,或另外一个字符串枚举成员进行初始化。
enum OrderType {
finish = 'Finish',
notPay = 'NotPay ',
cancel = 'Cancel'
}
异构枚举
从技术的角度来说,枚举可以混合字符串和数字成员,但是不建议这样做:
enum Flag {
No = 0,
Yes = "YES",
}
计算的和常量成员
枚举成员使用 常量枚举表达式初始化。 它可以在编译阶段求值。 当一个表达式满足下面条件之一时,它就是一个常量枚举表达式:
- 一个枚举表达式字面量(主要是字符串字面量或数字字面量)
- 一个对之前定义的常量枚举成员的引用(可以是在不同的枚举类型中定义的)
- 带括号的常量枚举表达式
- 一元运算符 +, -, ~其中之一应用在了常量枚举表达式
- 常量枚举表达式做为二元运算符 +, -, *, /, %, <<, >>, >>>, &, |, ^的操作对象。 若常数枚举表达式求值后为 NaN或 Infinity,则会在编译阶段报错。
所有其它情况的枚举成员被当作是需要计算得出的值。
enum suchAs{
// 常量
A,
B = 1,
C = 1+2,
D = a++,
// 计算量
E = "123".length
}
联合枚举与枚举成员的类型
这里还没看到联合类型所以只是了解个大概,先搬运个文档
存在一种特殊的非计算的常量枚举成员的子集:字面量枚举成员。 字面量枚举成员是指不带有初始值的常量枚举成员,或者是值被初始化为
任何字符串字面量(例如: “foo”, “bar”, “baz”)
任何数字字面量(例如: 1, 100)
应用了一元 -符号的数字字面量(例如: -1, -100)
当所有枚举成员都拥有字面量枚举值时,它就带有了一种特殊的语义。
首先,枚举成员成为了类型! 例如,我们可以说某些成员 只能是枚举成员的值:
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,
}
另一个变化是枚举类型本身变成了每个枚举成员的 联合。 虽然我们还没有讨论[联合类型](./Advanced Types.md#union-types),但你只要知道通过联合枚举,类型系统能够利用这样一个事实,它可以知道枚举里的值的集合。 因此,TypeScript能够捕获在比较值的时候犯的愚蠢的错误。 例如:
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'.
}
}
这个例子里,我们先检查 x是否不是 E.Foo。 如果通过了这个检查,然后 ||会发生短路效果, if语句体里的内容会被执行。 然而,这个检查没有通过,那么 x则 只能为 E.Foo,因此没理由再去检查它是否为 E.Bar。
运行时的枚举
枚举是在运行时真正存在的对象,可以作为变量传入
enum theEnum {
A, B, C
}
function fun(e) {
console.log(e)
}
fun(theEnum);
反向映射
在之前的例子中也应该看出来了(翻了一下,写在编辑器里了没粘过来,捂脸),枚举可以通过key找到value也可以通过value找到key
enum Enum {
A
}
let a = Enum.A;
let nameOfA = Enum[a]; // "A"
字符串枚举成员不会生成反向映射。
const枚举
const+枚举。声明一个常量枚举
const enum Enum {
A = 1,
B = A * 2
}
暂时还没想明白有啥意义,官网一句话解释就是
为了避免在额外生成的代码上的开销和额外的非直接的对枚举成员的访问
外部枚举
外部枚举用来描述已经存在的枚举类型的形状。
declare enum Enum {
A = 1,
B,
C = 2
}
declare关键词只会用于编译时的检查,编译结果中会被删除。