技术/翻译
原文链接:TypeScript Data Type - Enum
跟其他多数面向对象语言如Java、C#一样,Typescript同样支持Enum枚举类型。简单来说,枚举允许我们定义一组命名变量,该组变量可以是数字型或字符串型。
枚举类型包括:
- 数字枚举
- 字符串枚举
- 开发式枚举
让我们分布研究下各种枚举的样子:
数字枚举
顾名思义,数字枚举就是保存数值类型的枚举。
我们可以通过关键词enum
来定义一个枚举,现在来定义一个枚举PrintMedia
:
enum PrintMedia {
Newspaper,
Newsletter,
Magazine,
Book
}
上面我们定义了一个名为PrintMedia
的枚举,包括四个值分别是:Newspaper,Newsletter,Magazine,Book。需要了解的是枚举的成员变量值默认以数值来存储,第一个值通过是从0开始,并且其他值逐渐递增1,所以PrintMedia
的四个值分别是:
Newspaper = 0
Newsletter = 1
Magazine = 2
Book = 3
当然,我们可以改变第一个值的初始值,如下:
enum PrintMedia {
Newspaper = 1,
Newsletter, // 2
Magazine, // 3
Book // 4
}
我们给第一个元素指定值为1,则其他元素默认在第一个元素值的基础上逐渐递增加1。另外,枚举值不一定要是连续的值,可以指定随机数字:
enum PrintMedia {
Newspaper = 1,
Newsletter = 5,
Magazine = 10,
}
使用枚举作为函数返回值:
function getMediaType(media: string): PrintMedia {
if (media === 'Foris') {
return PrintMedia.Magazine
}
}
const mediaType: PrintMedia = getMediaType('Foris')
数字枚举的成员可以为任何表达式,最终返回一个数值即可;但是所有表达式成员必须在其他初始化成员最前面或最后面,这样TypeScript才能推断表达式应该返回的类型
如下面定义的枚举会导致报错:
enum PrintMedia {
Newsletter = getPrintMediaCode('newsletter'),
Newspaper, // Error: Enum member must have initializer
Book,
Magazine = Newsletter * 3,
}
// right
enum PrintMedia {
Newspaper,
Book,
Newsletter = getPrintMediaCode('newsletter'),
Magazine = Newsletter * 3
}
// or
enum PrintMedia {
Newsletter = getPrintMediaCode('newsletter'),
Magazine = Newsletter * 3,
Newspaper = 0,
Book,
}
字符串枚举
与数字型枚举类似,不过字符串枚举的成员变量值是以字符串来初始化的。字符串枚举的好处是字符串的可读性更好,尤其是我们在调试程序时,字符串要比数字要方便的多。
enum PrintMedia {
Newspaper = "NEWSPAPER",
Newsletter = "NEWSLETTER",
Magazine = "MAGAZINE",
Book = "BOOK"
}
// Access String Enum
PrintMedia.Newspaper; //returns NEWSPAPER
PrintMedia['Magazine'];//returns MAGAZINE
上面我们重新定义了一个字符串枚举PrintMedia
,同样包括四个值,但是使用字符串来替换数字,此外字符串枚举必须初始化。
开放式枚举
上面讲了数字枚举和字符串枚举,当然也存在一种枚举同时包括字符串和数字:
enum Status {
Active = 'ACTIVE',
Deactivate = 1,
Pending
}
那此时Pending的值应该是什么呢?字符串枚举必须初始化,数字枚举自动根据第一个值递增,所以Pending应该为2。
枚举逆向映射
先来看一下何为逆向映射:
PrintMedia.Magazine; // 3
PrintMedia[3] // Magazine
我们既可以通过成员变量名获取值,也可以根据值获取成员变量名,TypeScript同样支持这种逆向映射。
枚举原理分析
首先可以理解为一个枚举即是一个对象:
var PrintMedia = {}
定义一个成员变量:
PrintMedia['Magazine'] = 0
并且定义逆向映射:
PrintMedia[0] = 'Magazine'
当然,这只是简单实现,实际还要考虑字符串初始化的校验,数字枚举自动递增实现。
模拟枚举:
"use strict";
var PrintMedia;
(function(PrintMedia){
PrintMedia[PrintMedia["Newspaper"]=1]="Newspaper";
PrintMedia[PrintMedia["Newsletter"]=2]="Newsletter";
PrintMedia[PrintMedia["Magazine"]=3]="Magazine";
PrintMedia[PrintMedia["Book"]=4]="Book";
})(PrintMedia||(PrintMedia={}));
注意
: 逆向映射只适用数字枚举,字符串枚举并不支持,在开放式枚举中,也只有数字型枚举变量可以使用。一段代码解释原因:
enum PrintMedia{
Book='book',
Hello='book'
}
// js version
"use strict";
var PrintMedia;
(function(PrintMedia){
PrintMedia["Book"]="book";
PrintMedia["Hello"]="book";
})(PrintMedia||(PrintMedia={}));
枚举的两个成员变量初始化同一个字符串,如果支持逆向映射,那PrintMedia[‘book’]访问是哪个变量名?
今天又更新了,实在是今天在看TypeScript时看到这篇文章,感觉入门很通俗易懂就在看的时候随手翻译了,给大家分享一下。记得关注我的公众号【也寻常】,我们聊点别的~