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
关键字来定义常量枚举。常量枚举成员的值在编译阶段会被直接替换为它们的实际值,而不是在运行时计算。