TypeScript 枚举
枚举代表 枚举 。 枚举是TypeScript支持的一种新数据类型。它用于定义一组 命名常量 ,即一组相关值的集合。 TypeScript支持 数字 和 基于字符串 的枚举。我们可以使用 枚举 关键字来定义枚举。
为什么使用枚举
在TypeScript中,枚举很有用,因为它具有以下特点:
- 使用枚举可以使将来的值更改变得容易。
- 可以减少由于传输或输入错误数字而导致的错误。
- 枚举仅在编译时存在,因此不会分配内存。
- 可以通过JavaScript中的内联代码节省运行时和编译时。
- 允许我们创建与程序轻松关联的常量。
- 它使开发人员能够在不支持枚举的JavaScript中开发内存高效的自定义常量,但TypeScript帮助我们访问它们。
在TypeScript中有 三种 类型的枚举。它们是:
- 数值枚举
- 字符串枚举
- 异构枚举
数值枚举
数值枚举是基于 数字的 枚举,它以数字的形式存储值。这意味着我们可以将数字分配给枚举的实例。
示例
enum Direction {
Up = 1,
Down,
Left,
Right,
}
console.log(Direction);
在上面的示例中,我们有一个名为 Direction 的数字枚举。在这里,我们用1初始化 Up ,并从那个点开始 自增 所有后续成员。这意味着Direction.Up的值为1, Down 为2, Left 为3, Right 为4。
输出:
根据我们的需要,它还允许我们省略枚举的初始化。我们可以不进行初始化而声明枚举,如下所示。
enum Direction {
Up,
Down,
Left,
Right,
}
console.log(Direction);
这里,Up的值为0,所有随后的成员都是从该点开始自动递增的。这意味着Direction.Up的值为0,Down为1,Left为2,Right为3。 自动递增的行为在不需要关注成员值本身时非常有用。但是每个值在同一枚举中必须与其他值不同。
输出:
在TypeScript中的枚举中,不必总是为枚举成员分配 连续的 值。我们可以为枚举成员提供任何值,就像下面的示例一样。
示例
enum Direction {
Up=1,
Down=3,
Left=6,
Right=10,
}
console.log(Direction);
输出:
函数参数作为枚举类型
我们还可以将枚举类型用作函数的 参数类型 或 返回类型 ,如下面的示例所示。
enum AppStatus {
ACTIVE,
INACTIVE,
ONHOLD
}
function checkStatus(status: AppStatus): void {
console.log(status);
}
checkStatus(AppStatus.ONHOLD);
在上面的示例中,我们声明了一个枚举 AppStatus 。接下来,我们创建了一个函数 checkStatus() ,它接收一个输入参数status,并返回一个枚举类型的AppStatus。在函数中,我们 检查 status的类型。如果status的名称匹配,我们就得到了匹配的枚举成员。
输出:
在这里,我们可以看到在最后一条语句中打印的值“2”在大多数情况下是没有什么用的。这就是为什么它被 推荐 和 建议 使用基于字符串的枚举。
字符串枚举
字符串枚举与数值枚举是相似的概念,只是在运行时有一些细微的差异。在字符串枚举中,每个枚举值都是使用字符串字面值或另一个字符串枚举成员进行 常量初始化 ,而不是使用数值。
字符串枚举没有 自增 行为。使用此枚举的好处是字符串枚举提供更好的 可读性 。如果我们在调试程序,字符串枚举允许我们在代码运行时给出有意义和可读的值,而不考虑枚举成员本身的名称。
考虑以下将数值枚举表示为字符串枚举的示例:
示例
enum AppStatus {
ACTIVE = 'ACT',
INACTIVE = 'INACT',
ONHOLD = 'HLD',
ONSTOP = 'STOP'
}
function checkStatus(status: AppStatus): void {
console.log(status);
}
checkStatus(AppStatus.ONSTOP);
输出:
在上面的示例中,我们声明了一个字符串枚举 AppStatus ,其值与上面的数值枚举相同。但是字符串枚举与数值枚举不同,字符串枚举的值是使用 字符串字面量 进行初始化的。这两种枚举的区别在于数值枚举的值是自动递增的,而字符串枚举的值需要逐个初始化。
异构枚举
异构枚举是包含 字符串 和 数值 的枚举。但是建议只在需要利用JavaScript运行时行为时才这样做。
示例
enum AppStatus {
ACTIVE = 'Yes',
INACTIVE = 1,
ONHOLD = 2,
ONSTOP = 'STOP'
}
console.log(AppStatus.ACTIVE);
console.log(AppStatus.ONHOLD);
输出:
已计算和常量成员
我们知道每个枚举成员都有一个与其相关联的值。这些值可以是常量或计算得来的。我们可以将枚举成员视为 常量 如果:
1. 它是枚举的第一个成员,并且没有初始化值。在这种情况下,它将被赋值为0。
示例
// Name.Abhishek is constant:
enum Name {
Abhishek
}
console.log(Name);
2. 它没有初始化值,并且前一个枚举成员是一个数字常量。在这种情况下,当前枚举成员的值将是前一个枚举成员的值加一。
// All enum members in 'Name' and 'Profile' are constant.
enum Name {
Abhishek,
Ravi,
Ajay
}
enum Profile {
Engineer=1,
Leader,
Businessman
}
在TypeScript中,我们可以说,如果一个表达式满足以下条件,则为常量枚举表达式:
- 一个字面常量枚举表达式。
- 对先前定义的常量枚举成员的引用。
- 一个括号括起来的常量枚举表达式。
- 它是应用于常量枚举表达式的一元操作符:+, -,~。
- 与常量枚举表达式作为操作数的二元操作符:+, -, *, /, %, <<, >>, >>, &, |, ^。
在其他所有情况下,枚举成员被视为 计算得出的 。以下示例包含具有计算值的枚举成员:
enum Weekend {
Friday = 1,
Saturday = getDate('Dominoz'),
Sunday = Saturday * 40
}
function getDate(day : string): number {
if (day === 'Dominoz') {
return 3;
}
}
console.log(Weekend.Saturday);
console.log(Weekend.Sunday);
输出:
反向映射
TypeScript枚举也支持反向映射。这意味着我们可以访问枚举成员的值,也可以通过值访问成员名称。我们可以从下面的示例中理解反向映射。
注意: 字符串枚举不支持反向映射。
示例
enum Weekend {
Friday = 1,
Saturday,
Sunday
}
console.log(Weekend.Saturday);
console.log(Weekend["Saturday"]);
console.log(Weekend[3]);
输出结果:
枚举在运行时
枚举是实际存在于运行时的对象。我们可以从以下示例中理解它。
enum E {
A, B, C
}
实际上,它可以传递给函数,在下面的示例中我们可以看到。
function f(obj: { A: number }) {
return obj.A;
}
// Works, since 'E' has a property named 'A' which is a number.
f(E);
环境枚举
我们可以使用环境枚举来描述已经存在的枚举类型的形状。
Declare enum Enum{
X=1,
Y,
Z=2
}
主要有 ambient和非ambient枚举之间有一个区别。在常规枚举中,如果成员没有初始化器,则被视为 **常数,如果前面的枚举成员被视为常数。但是,没有初始化器的ambient(非常数)枚举成员始终被视为 **计算 枚举。