代码清晰的关键

在 TypeScript 的世界中,枚举是一个经常出现的概念。

TypeScript 虽然是相对较新的语言,却迅速成为开发者最青睐的编程语言之一。它本质上是 JavaScript 的扩展(或超集),这意味着任何有效的 JavaScript 代码都可以在 TypeScript 中运行。然而,TypeScript 的独特之处在于引入了静态类型的功能,这是 JavaScript 本身所缺乏的。

那么,究竟什么是 TypeScript 枚举?它们有哪些应用场景?又该如何创建它们呢?本文将深入探讨您需要了解的关于枚举的所有内容。

什么是 TypeScript 枚举?

枚举(也称为枚举类型)是一种长度固定的数据结构,用于存储一组不可变的值(常量)。TypeScript 并非唯一使用枚举的语言,它们在 C# 和 Java 等面向对象语言中也十分常见。

在 TypeScript 中,枚举允许开发者创建一组明确的案例或表达代码意图。它们对于定义只能取有限数量值的变量或属性尤为重要。例如,世界上只有七大洲,这是一个适合使用枚举的场景。

总结来说,TypeScript 枚举在以下几个方面具有重要意义:

  • 它们非常灵活,可以帮助开发者轻松地记录和表达代码意图及用例。
  • 枚举允许开发者在 JavaScript 中创建高效的自定义常量。
  • 在将 TypeScript 代码编译成 JavaScript 代码时,它们可以节省编译和运行时间。

TypeScript 枚举可以是数字或字符串形式。需要注意的是,这些枚举是经过预处理的,在测试阶段不会进行验证。TypeScript 会将枚举转换为相应的 JavaScript 代码。

TypeScript 中的不同枚举

现在您已经对枚举有了基本的了解,接下来让我们看看它们在 TypeScript 中是如何运作的。您可以在本地计算机上安装 TypeScript 和 Node.js,或者使用在线工具来搭建开发环境。我们将使用TypeScript Playground来演示不同的 TypeScript 枚举。

以下是 TypeScript 中常见的枚举类型:

#1. 数字枚举

您需要使用关键字 “enum”,后跟您要创建的枚举的名称。然后,使用花括号定义枚举的成员。以下是一个数字枚举的示例:

enum CardinalDirections {
  North = 5,
  East,
  South,
  West,
};

上述代码定义了一个名为 `CardinalDirections` 的枚举,它包含四个成员。在这种情况下,只能有四个值(北、东、南和西),这使得枚举成为存储此类数据的理想选择。

我们为 `CardinalDirections.North` 赋值为 5。但是,我们并没有为其他成员赋值,因为 TypeScript 会自动处理。例如,`CardinalDirections.East` 的值将为 6,因为 TypeScript 会将先前的值加 1。

`CardinalDirections.West` 的值将为 8。

如果我们不为花括号内的第一个成员赋值会怎么样?我们的枚举会变成这样:

enum CardinalDirections {
  North,
  East,
  South,
  West,
};

在这种情况下,TypeScript 会自动为 `North` 赋值为 0。如果您键入 `CardinalDirections.West`,您将得到 3。

#2. 字符串枚举

字符串枚举中的每个成员都必须使用另一个字符串枚举成员或字符串字面量进行初始化。以下是一个字符串枚举的示例:

enum Direction {
  Up = "UP",
  Down = "DOWN",
  Left = "LEFT",
  Right = "RIGHT",
}

字符串枚举不会像数字枚举那样递增。如果您运行以下代码:

enum Direction {
  Up = "UP",
  Down = "DOWN",
  Left = "LEFT",
  Right = "RIGHT",
}
console.log(Direction.Right)

您将得到以下结果:

“RIGHT”

#3. 异构枚举

您可以混合使用数字和字符串成员来创建异构枚举。这是一个示例:

enum HeterogeneousEnum {
  No = 0,
  Yes = "YES",
}

#4. 常量和计算枚举成员

枚举成员具有与之关联的值,这些值可以是“常量”或“计算的”。

以下是一个常量枚举的示例:

enum E1 {
  X,
  Y,
  Z,
}

在这种情况下,枚举的第一个成员没有初始值设定项,TypeScript 会为其赋值为 0。

再看看这个例子:

enum E1 {
  X=1,
  Y,
  Z,
}

这也是一个常量枚举,因为第一个成员被赋予了一个值,并且其余成员应用了递增规则。

计算枚举混合了常量和计算成员。看看这个例子:

enum Color {
  Red = 100,
  Green = (Math.random() * 100),
  Blue = 200
}

枚举成员 “Blue” 是常量成员。另一方面,枚举成员 “Green” 是在运行时使用 `Math.random()` 函数计算出来的。

#5. 常量枚举

常量枚举 (const enums) 用于提升数字枚举的性能。 在这种情况下,我们将枚举声明为 `const`。

考虑这段显示一周中日子的代码:

enum Weekday {
  Monday = 1,
  Tuesday,
  Wednesday,
  Thursday,
  Friday
}

如果我们运行 `console.log(Weekday.Thursday)`,我们得到的答案是 4。但是,如果我们检查编译时生成的 JavaScript 代码,我们会得到这样的结果:

"use strict";
var Weekday;
(function (Weekday) {
  Weekday[Weekday["Monday"] = 1] = "Monday";
  Weekday[Weekday["Tuesday"] = 2] = "Tuesday";
  Weekday[Weekday["Wednesday"] = 3] = "Wednesday";
  Weekday[Weekday["Thursday"] = 4] = "Thursday";
  Weekday[Weekday["Friday"] = 5] = "Friday";
})(Weekday || (Weekday = {}));
console.log(Weekday.Thursday);

我们可以修改这段代码,将 “Weekday” 声明为常量:

const enum Weekday {
  Monday = 1,
  Tuesday,
  Wednesday,
  Thursday,
  Friday
}

如果我们运行代码 `console.log(Weekday.Thursday)`,那么编译时生成的 JavaScript 代码将是:

"use strict";
console.log(4 /* Weekday.Thursday */);

您可以看到,当您将枚举声明为 `const` 时,编译后的 JavaScript 代码得到了优化。

#6. 环境枚举

环境枚举使用 `declare` 关键字来描述已经存在的枚举类型的形状。考虑以下示例:

declare enum Color {
  Red,
  Green,
  Blue
}

环境枚举在任何模块外部声明,可用于创建可重用类型。因此,只要它们是全局声明的,您始终可以导入环境枚举并在组件中使用它们。

现在您已经了解了 TypeScript 中不同的枚举类型。接下来,我们将展示如何以不同的方式使用枚举。以下是我们参考的代码:

enum Direction {
  North="N",
  East="E",
  South="S",
  West="W",
};

以下是一些用例:

  • 提取枚举成员。 例如,如果我们想访问 `North`,我们可以使用

console.log(Direction.North); // 输出:'N'

  • 使用枚举成员:您可以选择某个枚举成员来表示特定方向。 例如,
const currentDirection = Direction.East;
console.log(`The current direction is ${currentDirection}`);

这将输出 “当前方向是 E”。

TypeScript 中的枚举与对象映射

枚举用于表示一组有限的值。例如,彩虹的颜色或一周中的日子。枚举是强类型的,这意味着它们可以在开发过程中捕获任何类型错误。这是一个 TypeScript 枚举的示例:

enum Color {
  Red,
  Green,
  Blue,
}

对象映射(也称为字典或键值对)用于存储和检索与特定键关联的值。您可以使用 TypeScript 对象映射来存储任何类型的数据。但是,它们不是强类型的,这意味着在开发过程中可能不会捕获类型错误。以下是相同颜色的对象映射的示例:

const colors = {
  red: "FF0000",
  green: "00FF00",
  blue: "0000FF",
};

TypeScript 中枚举和对象映射之间的主要区别是:

  • 枚举是强类型的,而对象映射不是。
  • 枚举是一种“类型”,而对象映射是一种数据结构。
  • 枚举不灵活,而对象映射比较灵活。

在 TypeScript 中使用枚举的最佳实践

我们已经提到,TypeScript 并不是唯一具有枚举功能的编程语言。遵循最佳实践可以确保您编写的代码干净、优化且无错误。以下是编写/使用 TypeScript 枚举时的一些最佳实践:

  • 枚举名称大写:命名枚举时,始终将第一个单词大写。例如,建议使用枚举 “Number” 而不是 “number”。
  • 使用枚举作为常量:枚举最适合用来声明一组固定的相关项。例如,一周只能有 7 天。枚举成员在执行期间不应更改。
  • 避免过度使用枚举:您可能刚刚学习了一个新概念,并希望在 TypeScript 项目中几乎所有地方都使用它。但是,始终适度使用 TypeScript 枚举。当您想要保持代码可读性时,TypeScript 枚举是一个不错的选择。
  • 将枚举视为枚举:您可以将 TypeScript 枚举用于不同的目的。但是,最好只使用它们来表示枚举,而不是其他数据结构。
  • 避免自动枚举:如果您没有显式赋值,TypeScript 会为枚举成员自动赋值。请务必提供枚举值,以避免执行代码时出现意外行为。
  • 文档枚举:如果您打算让公众使用您的代码,请始终对您的代码进行记录或注释。解释每个枚举的作用以及为什么它是最佳用例。

作为开发人员,您还可以探索顶级的 TypeScript 库和运行时来扩展您的知识。

结论

本文介绍了如何在 TypeScript 中定义枚举,并解释了不同的类型及其用例。当您希望代码清晰易懂时,TypeScript 枚举非常有用。但是,在某些情况下,您应该避免使用它们,而选择对象。

例如,在处理动态值时不应使用枚举。您也不能使用枚举作为变量,否则您的程序会返回错误。

如果您仍然对 TypeScript 和 JavaScript 感到困惑,可以进一步了解 TypeScript 和 JavaScript 之间的差异。