typescript枚举的具体使用
作者:微 光
官方定义
使用枚举我们可以定义一些带名字的常量。 使用枚举可以清晰地表达意图或创建一组有区别的用例。 TypeScript支持数字的和基于字符串的枚举。枚举使用 enum
关键字来定义。
理解:
枚举是列举固定几个值,用于取值被限定在一定范围内的场景,比如一周只能有七天,颜色限定为红绿蓝等。
直接定义变量的话的话可以随意定义,枚举只能使用你定义好的几个值
例如你定义一个方法接收一个参数,这个参数如果是int型,别人在调用你这个方法时可以传1或2等任意数字,虽然你告诉了同事,只能传0或1,如果你把参数定义成只能传某个类型,例如是个枚举类,那么别人只能传你枚举类里定义好的几个类型,传其它的就会在编译时期报错。
按照枚举成员分类(数字、字符串、异构)
一、数字枚举
例1
enum Direction { Up, // 0 Down,// 1 Left,// 2 Right// 3 }
例2
enum Direction { Up = 1,// 1 Down,// 2 Left,// 3 Right// 4 }
例3
enum Direction { Up,// 0 Down=3,// 3 Left,// 4 Right// 5 }
例4
enum Days {Sun = 3, Mon = 1, Tue, Wed, Thu, Fri, Sat}; console.log(Days["Sun"] === 3); // true console.log(Days["Wed"] === 3); // true console.log(Days[3] === "Sun"); // false console.log(Days[3] === "Wed"); // true
以上四个例子我们可以看出
- 数字枚举如果没有初始化,默认初始化值为0,每项+1
- 如果有初始化,则在初始化值的基础上,每项+1
- 如果某项被赋值(可以是负数或负数),那么之后的项在此基础上+1
- 如果未手动赋值的枚举项与手动赋值的重复了,如例4,TypeScript 是不会察觉到这一点的,但建议尽量避免
反向映射
除了创建一个以属性名做为对象成员的对象之外,数字枚举成员(字符串枚举成员没有反向映射)还具有了 反向映射,从枚举值到枚举名字
enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat}; console.log(Days["Sun"] === 0); // true console.log(Days["Mon"] === 1); // true console.log(Days["Tue"] === 2); // true console.log(Days["Sat"] === 6); // true console.log(Days[0] === "Sun"); // true console.log(Days[1] === "Mon"); // true console.log(Days[2] === "Tue"); // true console.log(Days[6] === "Sat"); // true
二、字符串枚举
在一个字符串枚举里,每个成员都必须用字符串字面量,或另外一个字符串枚举成员进行初始化。
enum Direction { Up = "UP", Down = "DOWN", Left = "LEFT", Right = "RIGHT", }
三、异构枚举
将数字枚举与字符串枚举混用,但不建议
enum BooleanLikeHeterogeneousEnum { No = 0, Yes = "YES", }
按照声明方式(普通枚举,const 枚举,外部枚举,外部常量枚举)
一、普通枚举
上述例子都是常数项
值由计算所得变为计算所得项
如, "blue".length
就是一个计算所得项
enum Color {Red, Green, Blue = "blue".length};
以下情况不被允许
enum Color {Red = "red".length, Green, Blue};
根据官方定义,不带初始化器的枚举要么被放在第一的位置,要么被放在使用了数字常量或其它常量初始化了的枚举后面。
上述代码会报错,因为Red是计算项,而Green紧接其后却无法获取初始值
二、常数枚举 ( const enum 定义的枚举)
const enum Directions { Up, Down, Left, Right } let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];
会被编译为
var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */];
常数枚举与普通枚举的区别是,它会在编译阶段被删除,并且不能包含计算成员,假如包含了计算成员,则会在编译阶段报错。
三、外部枚举( declare enum 定义的枚举)
种声明枚举的方式比较特别,使用的时候需要非常谨慎,该枚举类型不会生成反向映射
// 声明语 + 关键词 + 枚举名称 declare enum ChineseZodiac { rat = 1, cattle, tiger, rabbit, dragon } console.log(ChineseZodiac) console.log(ChineseZodiac.rat)
你会发现,无论你是访问枚举本身还是内部成员,均会报错: ChineseZodiac is not defined编译之后并没有生成该枚举,也就是说,声明的外部枚举是没有被编译的,导致在 runtime 的时候就会报错这就让人很头疼,既然不能访问,那为何要能做出这个声明呢。
官网对其的描述是:外部枚举用来描述已经存在的枚举类型的形状,这样听起来很晦涩。
通过代码来分析
外部枚举是为了描述当前环境中已经存在的对象的,这个对象可以存在任意的地方,但是一定是已声明的;1-1- 一个 .html
后缀文件,为了引入 .ts
文件编译之后的结果,用于调试
1-2- .ts
源文件
1-3- 编译之后的 .js
文件
1-4- 其他 .js
资源文件
1-5- 访问结果
会发现是不会报错的,但是你可能会疑问了,这个不就是访问自己声明的一个变量吗,那跟 .ts
文件中声明的枚举有什么关系?图样图森破,外部枚举类似于 ts
的类型断言,只要在开发中有这个声明,意味着在当前开发环境上下文中一定存在当前这个对象,你可以随意使用当前对象;当然也就意味着你声明外部枚举的时候慎重,我是否真的需要这样做,不然 runtime
使用的时候就出错了;
外部枚举还可以防止声明枚举的命名冲突和成员冲突
2-1- 我在上面文件结构基础上新增了一个 enum.ts
文件,并在里面声明了一个普通枚举,但是枚举成员和外部枚举成员相同
2-2- 之所以会有这样的提示,是 declare
的作用,因为 ts
类型系统能够侦测到当前整个文件目录上下文中的所有 declare
声明的变量,编译器也会有语法提示;
四、外部常量枚举(declare 和 const 关键词联合声明)
这个枚举类型和 const
枚举类型并没有什么区别,只是会提示是否有枚举命名冲突和成员冲突,该枚举类型不会生成反向映射
// 声明语 + 修饰符 + 关键词 + 枚举名称 declare const enum ChineseZodiac { rat = 1, cattle, tiger, rabbit, dragon } ChineseZodiac.dragon => 5/* dragon */
到此这篇关于typescript枚举的具体使用的文章就介绍到这了,更多相关typescript枚举内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!