TypeScript入门到精通——TypeScript类型系统基础——枚举类型
TypeScript类型系统基础——枚举类型
枚举类型由零个或多个枚举成员构成,每个枚举成员都是一个命名的常量。
在 TypeScript 中,枚举类型是一种原始类型,它通过 enum 关键字来定义。例如,我们可以使用枚举类型来表示一年四季,示例如下:
enum Season{ Spring, Summer, Fall, Winter, }
按照枚举成员的类型可以将枚举类型划分为以下三类:
- 数值型枚举
- 字符串枚举
- 异构性枚举
1、数值型枚举
数值型枚举是最常用的枚举类型,是 number 类型的子类型,它由一组命名的数值常量构成。定义数值型枚举的方法如下所示:
enum Direction { Up, Dwon, Left, Right } const direction: Direction = Direction.up;
此示例中,我们使用 enum 关键字定义了枚举类型 Direction,它包含了四个枚举成员 Up、Down、Left 和 Right。在使用枚举成员时,可以像访问对象属性一样访问枚举成员。
如果想要为枚举成员设置初始值,可以直接在成员名称后面赋值。例如,让 Up
的值为 1,其它成员的值依次递增:
enum Direction {
Up = 1,
Down,
Left,
Right
}
在这个例子中,Up
的值是 1,Down
的值是 2,Left
的值是 3,Right
的值是 4。
代码示例是一个 TypeScript 的数值型枚举。在这个示例中,Up 的值被显式设置为 1,Down 的值会自动递增为 2。然后,Left 的值被显式设置为 10,Right 的值会自动递增为 11,所以在这个例子中,各个枚举成员的值如下:
-
Up
: 1Down
: 2Left
: 10Right
: 11
这种自动递增的特性使得枚举在需要一组相关常量时非常方便。同时,你也可以为特定的枚举成员设置特定的值。
2、字符串枚举
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT"
}
在这个例子中,Up
的值是 "UP",Down
的值是 "DOWN",Left
的值是 "LEFT",Right
的值是 "RIGHT"。每个枚举成员的值都是显式指定的字符串字面量。
与数值型枚举不同,字符串枚举成员的值不会递增。这是因为字符串枚举成员的值是字符串类型,而不是数字类型。因此,每个成员的值都必须显式指定。
字符串枚举是 string 类型的子类型,因此允许将字符串枚举类型赋值给 string 类型。例如,下列中常量 direction 为 string 类型,可以使用字符串枚举 Direction 来初始化 direction 常量,以下是一个示例:
enum Direction { Up = "UP", Down = "DOWN", Left = "LEFT", Right = "RIGHT" } const direction: string = Direction.Up;
direction
的常量,它的类型是string
。然后,我们使用Direction.Up
来初始化direction
常量。这是合法的,因为Direction.Up
的类型是string
,与direction
常量的类型兼容。需要注意的是,虽然可以将字符串枚举类型的值赋给 string 类型的变量,但反过来并不总是成立。也就是说,不是所有的 string 类型的值都可以赋给字符串枚举类型的变量,只有那些与枚举成员名称匹配的字符串字面量才可以。这是因为字符串枚举类型的值是有限的,只包括那些显式指定的枚举成员的值。
3、异构型枚举
在 TypeScript 中,异构型枚举(Heterogeneous Enum)是一种特殊的枚举类型,它允许在一个枚举中混合使用不同的数据类型,如数值和字符串。在异构型枚举中,不同的成员可以有不同的数据类型,这使得它们非常灵活,但也需要格外小心,以避免类型错误。
下面是一个异构型枚举的示例:
enum MixedEnum {
NumericMember = 1,
StringMember = "Hello",
AnotherNumericMember = 2.5,
BooleanMember = true
}
在这个例子中,MixedEnum
是一个异构型枚举,包含了不同类型的成员。NumericMember
是一个数值类型的成员,值为 1;StringMember
是一个字符串类型的成员,值为 "Hello";AnotherNumericMember
是另一个数值类型的成员,值为 2.5;BooleanMember
是一个布尔类型的成员,值为 true。
需要注意的是,在异构型枚举中,成员的类型是根据其值来推断的。因此,尽管NumericMembe
和AnotherNumericMember
没有显式指定类型,但由于它们的值是数值,所以它们被认为是数值型成员。而StringMember
的值是字符串,所以它被认为是字符串型成员;BooleanMember
的值是布尔值,所以它被认为是布尔型成员。
异构型枚举在使用时需要格外小心,因为不同类型成员之间的操作可能会导致类型错误。例如,将字符串成员与数值成员相加将会导致一个类型错误。为了避免这种情况,最好在使用异构型枚举时明确指定成员的类型。
4、枚举成员映射
不论是哪种类型的枚举,都可以通过枚举成员名去访问枚举成员值。下列中,通过枚举名Bool和枚举成员False与True能够访问枚举成员的值:
以下是一个示例:
enum Bool { False = 0, True = 1 } console.log(Bool.False); // 输出 0 console.log(Bool.True); // 输出 1
5、常量枚举成员与计算枚举成员
5.1、常量枚举成员
常量枚举成员是指在编译阶段就能够被确定的枚举成员。在TypeScript中,可以使用const enum
关键字来定义常量枚举。常量枚举成员的值在编译阶段会被直接替换为它们的实际值,而不是在运行时计算。
以下是一个常量枚举的示例:
const enum Direction {
Up,
Down,
Left,
Right
}
在这个例子中,Up
的值是 0,Down
的值是 1,Left
的值是 2,Right
的值是 3。这些值在编译阶段就会被确定,并且会被直接替换为它们的实际值。
需要注意的是,由于常量枚举成员的值在编译阶段就会被确定,所以它们不能被用于计算其他枚举成员的值。此外,常量枚举只能在 TypeScript 代码中使用,不能在 JavaScript 代码中使用。
5.2、计算枚举成员
enum Color { Red, Green, Blue = Red + Green, Cyan = Red + Green + Blue }
在这个例子中,Red
的值是 0,Green
的值是 1,Blue
的值是 Red + Green
的结果,即 1,Cyan
的值是Red+Green+Blue
的结果,即 2。这些值是在运行时计算的,而不是在编译阶段确定的。
需要注意的是,计算枚举成员的值必须在运行时才能确定,因此它们不能被用于常量枚举中。此外,由于计算枚举成员的值是在运行时计算的,所以它们可能会对性能产生一定的影响。
6、联合枚举类型
当枚举类型中的所有成员都是字面量枚举成员时,该枚举类型成立联合枚举类型。
6.1、联合枚举成员类型
联合枚举成员类型是指联合枚举中每个枚举成员的类型。由于联合枚举中的所有成员都是字面量枚举成员,因此它们的类型都是字面量类型,例如 number、string、boolean 等。
以下是一个联合枚举的示例:
enum Shape { Circle = "circle", Square = "square", Triangle = "triangle" }
在这个例子中,Shape
是一个联合枚举类型,包含了三个字符串类型的成员:Circle
、Square
和Triangle
。每个成员的类型都是string。
6.2、联合枚举类型
联合枚举类型是指由联合枚举成员类型组成的整体类型。在TypeScript中,可以使用联合类型来表示多个类型的组合。
以下是一个联合枚举类型的示例:
enum Shape {
Circle = "circle",
Square = "square",
Triangle = "triangle"
}
function drawShape(shape: Shape): void {
// 根据 shape 的值绘制不同的形状
}
在这个例子中,drawShape
函数的参数shape
的类型是Shape
,它是一个联合枚举类型,包含了Circle
、Square
和Triangle
三个成员。函数体内部可以根据shape
的值来绘制不同的形状。
6.3、联合枚举类型的起源和解决的问题
联合枚举类型是TypeScript中的一个特性,旨在更好地处理枚举类型。在早期的JavaScript中,枚举通常使用一组具名常量来表示,但这种方式存在一些问题,例如类型不安全、容易出错等。TypeScript 引入了枚举类型来解决这些问题,而联合枚举类型是其中的一种特殊形式。
联合枚举类型的主要优点是可以将多个字面量类型组合在一起,形成一个整体类型。这使得在函数参数、变量声明等地方可以使用更加精确的类型,提高了代码的类型安全性和可维护性。同时,联合枚举类型还可以与TypeScript的其他特性(如类型保护、类型断言等)结合使用,实现更加灵活和强大的类型操作。
7、const 枚举类型
枚举类型是 TypeScript 对 JavaScript 的扩展,JavaScript 语言本身并不支持枚举类型。在编译时,TypeScript 编译器会将枚举类型编译为 JavaScript 对象。
例如,我们定义如下的枚举:
enum Direction { Up, Down, Left, Right, } const d: Direction = Direction.Up
定义了一个名为Direction
的枚举类型,并且声明了一个名为d
的常量并赋值为Direction.Up
。在TypeScript中,你可以通过枚举的名称(在本例中为Direction
)和枚举成员的名称(在本例中为Up
)来访问枚举成员的值。d
常量的值将被设置为0
,因为Up
是Direction
枚举的第一个成员,其默认值为0
。