了解TypeScript枚举| 常量和环境枚举
TypeScript中的Enum允许我们定义一组命名常量。 枚举或枚举是TypeScript支持的新数据类型。 使用枚举使我们的生活更容易记录意图或创建一组不同的案例。 TypeScript提供数字枚举和基于字符串的枚举。
对于本教程,您必须在环境中安装TypeScript。
如果尚未安装,则可以使用NPM进行安装。
npm install -g typescript
它将全局安装在您的计算机中。
现在,您可以使用以下命令进行编译。
tsc filename.ts
枚举类型
枚举分为三种:
- 数值枚举
- 字符串枚举
- 异构枚举
数值枚举
要定义数字枚举,请使用enum关键字。
// app.ts enum score { batsman, bowler, fielder, Umpire, }
现在,让我们通过以下命令转换该文件。
tsc app.ts
它将在同一目录中创建app.js文件。
app.js文件的内容如下。
// app.js var score; (function (score) { score[score["batsman"] = 0] = "batsman"; score[score["bowler"] = 1] = "bowler"; score[score["fielder"] = 2] = "fielder"; score[score["Umpire"] = 3] = "Umpire"; })(score || (score = {}));
JavaScript Transpiler将发出查找表,该表看起来像上面的表。
当您在TypeScript中拥有score.batsman时,它将在JavaScript中发出score.batsman,其值为0。
比分[0] 发出分数[0] 并评估为“击球手”。 反向查找选项是枚举所独有的,并且非常方便。
存储时,TypeScript中的枚举始终分配有数值。 第一个值始终为数字值0,而枚举中的其他属性值增加1。
我们还可以选择自己初始化第一个数字值。 例如,我们可以编写与以下相同的枚举。
enum score { batsman = 100, bowler, fielder, Umpire, }
现在,转换为JavaScript。
tsc app.ts
它将创建一个app.js文件。
var score; (function (score) { score[score["batsman"] = 100] = "batsman"; score[score["bowler"] = 101] = "bowler"; score[score["fielder"] = 102] = "fielder"; score[score["umpire"] = 103] = "Umpire"; })(score || (score = {}));
在此示例中,我们将击球手初始化为100,然后,它将以1递增到以下属性。
这就是为什么我们得到礼帽= 101,外野手= 102和裁判= 103的原因。
枚举作为函数参数
枚举可以用作函数参数。 让我们看看如何将枚举作为函数参数传递。
// app.ts enum data { x = 19, y = 21 } function respond(recipient: string, message: data): void { console.log(recipient + message) } respond("The value of x is: ", data.x)
在此示例中,我们定义了一个名为data的枚举。
然后,我们定义了一个名为response()的函数,该函数带有两个参数。
- 收件人–这是一种字符串。
- 消息–这是我们最近定义的一种枚举。
然后在正文中,我们同时打印两个参数,然后调用response()方法。
使用枚举很简单:只需将任何成员作为枚举本身的属性进行访问,并使用枚举的名称声明类型。
如果转换为Javascript并运行JavaScript代码,则将看到以下输出。
node app The value of x is: 19
TypeScript中的计算枚举
数值枚举可以包含具有计算数值的成员。
枚举成员的值可以是常量,也可以是计算值。
以下枚举包括具有计算值的成员。
// app.ts enum Millie { x = 19, y = 21, z = fetchValue('Eleven') } function fetchValue(val: String) { if (val == 'Eleven') { return 11 } else { return 21 } } console.log(Millie.z)
转换为Javascript代码并运行文件。 您将看到以下输出。
11
但是,当我们使用计算机枚举时,有一个警告。
不带初始化器的枚举要么必须首先使用,要么必须在使用数字常量或其他常量枚举成员初始化的数字枚举之后出现。
换句话说,当枚举包括计算成员和常量成员时,未初始化的枚举成员必须首先出现,或者必须在具有数字常量的其他初始化成员之后出现。
如果执行以下代码,则会收到错误消息。
// app.ts enum Millie { x = 19, z = fetchValue('Eleven'), y } function fetchValue(val: String) { if (val == 'Eleven') { return 11 } else { return 21 } } console.log(Millie.z)
在上面的代码中,您可以看到z具有计算属性,而下一个y没有初始化。
如果您尝试转译文件,则将出现以下错误。
app.ts:4:3 –错误TS1061:枚举成员必须具有初始化程序。
为了避免上述错误,可以将以下枚举声明为以下形式。
enum Millie { x = 19, y, z = fetchValue('Eleven'), }
现在,它不会给出任何错误。
字符串枚举
字符串枚举与数字枚举相似,但枚举值是使用字符串值而不是数字值初始化的。
使用字符串枚举的优点是字符串枚举提供了更好的可读性。 如果必须调试代码,则读取字符串值比读取数字值更容易。
如果输出变量的值,则不会得到神秘的0或1;否则,将不会得到神秘值。 您每次都会获得实际的字符串本身。 因此,它还可以轻松地进行JSONifiable并生成您可以用其他语言阅读的JSON,而无需维护其他语言的枚举映射。
// app.ts enum StrangerThings { Character = "Eleven", Father = "Hopper", Power = "Telekenesis", Town = "Hawkins" } console.log(StrangerThings.Character) console.log(StrangerThings.Power)
输出量
Eleven Telekenesis
在上面的代码中,我们定义了字符串枚举StrangerThings,其值与上面的数字枚举相同,但区别在于这些枚举值是用字符串文字初始化的。
数字枚举和字符串枚举之间的区别在于,数字枚举值是自动递增的,而字符串枚举值需要单独初始化。
假设如果您不初始化父亲属性,那么您将得到如下错误。
app.ts:3:3 –错误TS1061:枚举成员必须具有初始化程序。
例如,尝试翻译以下代码。
// app.ts enum StrangerThings { Character = "Eleven", Father, Power = "Telekenesis", Town = "Hawkins" } console.log(StrangerThings.Character) console.log(StrangerThings.Power)
在此示例中,父未初始化。 因此,它将给我们带来错误。
如果您甚至将其初始化为空字符串,那么也不会出现任何错误。
// app.ts enum StrangerThings { Character = "Eleven", Father = "", Power = "Telekenesis", Town = "Hawkins" } console.log(StrangerThings.Character) console.log(StrangerThings.Father)
输出量
Eleven
它将打印空字符串。
如果您正在调试代码并且必须读取数字枚举的运行时值,则该值通常是不透明的,它本身并不能传达任何有用的含义(尽管反向映射通常可以提供帮助),字符串枚举使我们能够代码运行时有意义的,可读的值,与枚举成员本身的名称无关。
异构枚举
异构枚举包含字符串和数字值。
// app.ts enum StrangerThings { Character = "Eleven", Father = "", Power = "Telekenesis", age = 15 } console.log(StrangerThings.Character) console.log(StrangerThings.age)
输出量
➜ tsc app.ts ➜ node app Eleven 15
除非您试图以一种智能方式利用JavaScript的运行时行为,否则建议您不要使用异构枚举。
反向映射
TypeScript枚举支持反向映射。 反向映射意味着我们可以访问成员的值以及成员的值。
// app.ts enum StrangerThings { Character = 11, Father, Power, age = 15 } console.log(StrangerThings.Power) console.log(StrangerThings["Power"]) console.log(StrangerThings[13])
输出量
➜ tsc app.ts ➜ node app 13 13 Power
从上面的代码中,StrangerThings[13] 返回其成员名称“ Power”。 这是由于反向映射。
让我们使用以下示例学习TypeScript如何实现反向映射。
// app.ts enum StrangerThings { Character = 11, Father, Power, age = 15 } console.log(StrangerThings)
输出量
➜ tsc app.ts ➜ node app { '11': 'Character', '12': 'Father', '13': 'Power', '15': 'age', Character: 11, Father: 12, Power: 13, age: 15 }
从输出中,您可以看到该枚举的每个值在内部存储的枚举对象中出现两次。 我们知道可以使用相应的枚举成员值来检索枚举值。
但是,确实可以使用其值检索枚举成员。
这就是我们所谓的反向映射。
因此,以下两个映射都适用于枚举:name-> value和value-> name。
常量枚举
在大多数情况下,枚举是一个非常有效的解决方案。 但是,有时要求更加严格。 为了避免在访问枚举值时支付额外的生成代码的开销,可以使用const枚举。
const枚举是在我们的枚举上使用const修饰符定义的。
我们可以编写以下代码来定义const枚举。
const enum Dark { Mikkel, Jonas } console.log(Dark.Mikkel) console.log(Dark['Mikkel']) console.log(Dark.Jonas) console.log(Dark['Jonas'])
输出量
➜ tsc app.ts ➜ node app 0 0 1 1
与往常一样,枚举在存储时始终分配有数值。
第一个值始终为0,而枚举中的其他值均增加1。
但是黑暗呢[0]? 这将在运行时出错,并且编译器应该捕获它。 没有查找表,并且编译器未在此处内联。
// app.ts const enum Data { Mikkel, Jonas } console.log(Data[0]) console.log(Data[1])
输出量
app.ts:3:18 - error TS2476: A const enum member can only be accessed using a string literal. 3 console.log(Dark[0]) ~ app.ts:4:18 - error TS2476: A const enum member can only be accessed using a string literal. 4 console.log(Dark[1]) ~ Found 2 errors.
在这里,我们得到:const枚举成员只能使用字符串文字进行访问。
在上面的代码中,–preserveConstEnumsflag将使Dark发出查找表。 但是,其值仍将内联。
环境枚举
环境枚举用于描述已经存在的枚举类型的形状。
declare enum Enum { A = 11, B, C = 21 }
环境枚举和非环境枚举之间的关键区别在于,在常规枚举中,如果没有其初始值设定项的成员被视为常量,则将其视为常量。
相反,始终将没有初始化程序的环境(和非const)枚举成员视为已计算。
结论
以下是枚举在TypeScript中派上用场的一些原因:
- 使用TypeScript枚举,您可以创建可以轻松关联的常量,使常量更具可读性。
- 使用TypeScript枚举,开发人员可以自由地在JavaScript中开发内存有效的自定义常量。 JavaScript不支持枚举,但是TypeScript可以帮助我们构建和访问它们。
- TypeScript枚举使用JavaScript中的内联代码节省运行时和编译时。
- TypeScript枚举还支持我们以前仅在像Java这样的编程语言中拥有的某些灵活性。 这种多功能性使您可以轻松有效地表达和记录我们的目标和用例。
枚举可以在数组初始化中使用,就像其他TypeScript数据类型一样。
在某些情况下,您不使用ts枚举。
- TypeScript枚举不能用作变量; 这样做会返回错误。
- 当您计划重新分配或修改枚举成员值时,枚举是类型安全的,因此,在重新分配时将返回编译错误。
- 当您需要记录动态值时,枚举最适合于有限元,其背后的总体思路是帮助构建用户定义的常数系统。
那是针对TypeScript枚举教程的。
也可以看看
TypeScript入门
使用Webpack设置TypeScript
在Vue中使用TypeScript