可以定义一些带名字的常量,暂时只支持数字的和基于字符串的枚举。
一、枚举
1,数字枚举
会从0自增
enum Direction {
Up, // 输出0 // 从0开始自增
Down, // 输出1
Left = 3, // 输出3 // 赋值
Right, // 输出4 // 赋值后自增
}
function respond(recipient: string, message: Direction): void { // 枚举可以作为类型
// ...
}
respond("Princess Caroline", Direction.Down) // 枚举也可以直接读取
没有初始化器的成员要么在首位,要么必须在用数值常量或其他常量枚举成员初始化的数值枚举之后
enum E {
A = getSomeValue(),
B, // 出错,没有初始化的数字枚举要么在首位,要么必须在用数值常量或其他常量枚举成员初始化的数值枚举之后
}
2,字符串枚举
// 由于字符串没有自增的肯可能,所以申明时,必须初始化
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
3,异构枚举
// 混合字符串和枚举,用的少
enum BooleanLikeHeterogeneousEnum {
No = 0,
Yes = "YES",
}
4,计算的和常量成员
// 常量枚举申明方式有:
// 类型1:没有初始化值的
enum E { X } // X=0
//类型2:枚举成员是数字
enum E2 {
A = 1, B, C // B=2, C=3
}
//类型3:常量枚举表达式 // 若常量枚举表达式求值后为 NaN 或 Infinity ,则会在编译阶段报错。
enum FileAccess {
// constant members
None,
Read = 1 + 1,
Write = 1 % 2,
ReadWrite = Read | Write,
// computed member
G = "123".length
}
5,联合枚举与枚举成员的类型
字面量枚举成员(非计算的常量枚举成员的子集)的枚举成员成为了类型,并且本身变成了每个枚举成员的联合
// 1,枚举成员成为了类型
enum ShapeKind {
Circle,
Square,
}
interface Circle {
kind: ShapeKind.Circle;
radius: number;
}
interface Square {
kind: ShapeKind.Square;
sideLength: number;
}
let c: Circle = {
kind: ShapeKind.Square, // 错误,ShapeKind.Square类型不是ShapeKind.Circle类型
radius: 100,
}
// 2,本身变成了每个枚举成员的联合
enum E {
Foo,
Bar,
}
function f(x: E) {
if (x !== E.Foo || x !== E.Bar) {
// ~~~~~~~~~~~
// 出错 既然申明了参数为类型E,那么x只能从E类型中获取,E变成了一个联合类型
}
}
6,运行时的枚举
枚举可以是类型,也可以是真正存在的对象
enum E {
X, Y, Z
}
function f(obj: { X: number }) {
return obj.X;
}
// 没问题,因为 'E'包含一个数值型属性'X'。
f(E);
7,编译时的枚举
enum LogLevel {
ERROR, WARN, INFO, DEBUG
}
/**
* 等同于:
* type LogLevelStrings = 'ERROR' | 'WARN' | 'INFO' | 'DEBUG';
*/
type LogLevelStrings = keyof typeof LogLevel; // 使用 keyof typeof 来获取一个表示枚举里所有字符串 key 的类型,而不是keyof
function printImportant(key: LogLevelStrings, message: string) {
const num = LogLevel[key];
if (num <= LogLevel.WARN) {
console.log('Log level key is: ', key);
console.log('Log level value is: ', num);
console.log('Log level message is: ', message);
}
}
printImportant('ERROR', 'This is a message');
// 反向映射
enum Enum {
A
}
let a = Enum.A;
let nameOfA = Enum[a]; // "A"
// 相当于
var Enum;
(function (Enum) {
Enum[Enum["A"] = 0] = "A";
})(Enum || (Enum = {}));
var a = Enum.A;
var nameOfA = Enum[a]; // "A"
// 常量枚举
const enum Directions {
Up,
Down,
Left,
Right
}
let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right]
// 编译后生成
var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */];
二、外部枚举
// 普通枚举
enum Students{weizexu,weixinyao,lizhihao};
console.log(Students.lizhihao); // 2
// 外部枚举
declare enum Students{weizexu,weixinyao,lizhihao};
console.log(Students.lizhihao); // Students is not defined