TypeScript入门教程 之 枚举 Enums

枚举是一种组织相关值集合的方法。许多其他编程语言(C / C#/ Java)具有enum数据类型,而JavaScript没有。但是,TypeScript可以。这是TypeScript枚举的示例定义:

enum CardSuit {Clubs,Diamonds,Hearts,Spades
}// Sample usage
var card = CardSuit.Clubs;// Safety
card = "not a member of card suit"; // Error : string is not assignable to type `CardSuit`

这些枚举值是numbers,因此从此以后我将它们称为Number Enums。

数字枚举和数字

TypeScript枚举基于数字。这意味着可以将数字分配给枚举的实例,与兼容的其他任何事物也可以赋值number

enum Color {Red,Green,Blue
}
var col = Color.Red;
col = 0; // Effectively same as Color.Red

数字枚举和字符串

在进一步研究枚举之前,让我们看一下它生成的JavaScript,这里是一个示例TypeScript:

enum Tristate {False,True,Unknown
}

生成以下JavaScript:

var Tristate;
(function (Tristate) {Tristate[Tristate["False"] = 0] = "False";Tristate[Tristate["True"] = 1] = "True";Tristate[Tristate["Unknown"] = 2] = "Unknown";
})(Tristate || (Tristate = {}));

让我们专注于线上Tristate[Tristate["False"] = 0] = "False";。在其中Tristate["False"] = 0应具有自我解释性,即将变量"False"成员设置Tristate0。请注意,在JavaScript中,赋值运算符返回分配的值(在本例中为0)。因此,JavaScript运行时执行的下一件事是Tristate[0] = "False"。这意味着您可以使用该Tristate变量将枚举的字符串版本转换为数字,或者将枚举的数字版本转换为字符串。如下所示:

enum Tristate {False,True,Unknown
}
console.log(Tristate[0]); // "False"
console.log(Tristate["False"]); // 0
console.log(Tristate[Tristate.False]); // "False" because `Tristate.False == 0`

更改与数字枚举关联的数字

默认情况下,枚举是0基础,然后每个后续值自动加1。例如,考虑以下内容:

enum Color {Red,     // 0Green,   // 1Blue     // 2
}

但是,可以通过专门分配给任何枚举成员来更改与该枚举成员关联的数字。如下所示,我们从3开始并从那里开始递增:

enum Color {DarkRed = 3,  // 3DarkGreen,    // 4DarkBlue      // 5
}

提示:我通常使用来初始化第一个枚举, = 1因为它允许我对枚举值进行安全的真实检查。

数字枚举作为标志

枚举的一种出色用法是能够将枚举用作Flags。标志允许您检查一组条件中的某个条件是否为真。考虑以下示例,其中我们具有一组有关动物的属性:

enum AnimalFlags {None           = 0,HasClaws       = 1 << 0,CanFly         = 1 << 1,EatsFish       = 1 << 2,Endangered     = 1 << 3
}

这里我们使用左移操作符来移动1周围位的一定水平拿出按位不相交的数字0001001001001000(这些都是小数1248如果你很好奇)。当使用标志时,按位运算符|(or)/ &(and)/ ~(not)是您最好的朋友,并在下面进行演示:

enum AnimalFlags {None           = 0,HasClaws       = 1 << 0,CanFly         = 1 << 1,
}
type Animal = {flags: AnimalFlags
}function printAnimalAbilities(animal: Animal) {var animalFlags = animal.flags;if (animalFlags & AnimalFlags.HasClaws) {console.log('animal has claws');}if (animalFlags & AnimalFlags.CanFly) {console.log('animal can fly');}if (animalFlags == AnimalFlags.None) {console.log('nothing');}
}let animal: Animal = { flags: AnimalFlags.None };
printAnimalAbilities(animal); // nothing
animal.flags |= AnimalFlags.HasClaws;
printAnimalAbilities(animal); // animal has claws
animal.flags &= ~AnimalFlags.HasClaws;
printAnimalAbilities(animal); // nothing
animal.flags |= AnimalFlags.HasClaws | AnimalFlags.CanFly;
printAnimalAbilities(animal); // animal has claws, animal can fly

这里:

  • 我们曾经|=添加标志
  • &=~清除标志的组合
  • | 组合标志

注意:您可以组合标志以在枚举定义内创建方便的快捷方式,例如EndangeredFlyingClawedFishEating

enum AnimalFlags {None           = 0,HasClaws       = 1 << 0,CanFly         = 1 << 1,EatsFish       = 1 << 2,Endangered     = 1 << 3,EndangeredFlyingClawedFishEating = HasClaws | CanFly | EatsFish | Endangered,
}

字符串枚举

我们只看了成员值为numbers的枚举。实际上,您也可以让枚举成员具有字符串值。例如

export enum EvidenceTypeEnum {UNKNOWN = '',PASSPORT_VISA = 'passport_visa',PASSPORT = 'passport',SIGHTED_STUDENT_CARD = 'sighted_tertiary_edu_id',SIGHTED_KEYPASS_CARD = 'sighted_keypass_card',SIGHTED_PROOF_OF_AGE_CARD = 'sighted_proof_of_age_card',
}

这些可以提供有意义的/可调试的字符串值,因此更易于处理和调试。

您可以使用这些值进行简单的字符串比较。例如

// Where `someStringFromBackend` will be '' | 'passport_visa' | 'passport' ... etc.
const value = someStringFromBackend as EvidenceTypeEnum; // Sample use in code
if (value === EvidenceTypeEnum.PASSPORT){console.log('You provided a passport');console.log(value); // `passport`
}

常量枚举

如果您具有如下的枚举定义:

enum Tristate {False,True,Unknown
}var lie = Tristate.False;

该行var lie = Tristate.False被编译为JavaScript var lie = Tristate.False(是的,输出与输入相同)。这意味着,在执行运行时将需要查找Tristate,然后Tristate.False。要提高性能,您可以将标记enumconst enum。如下所示:

const enum Tristate {False,True,Unknown
}var lie = Tristate.False;

生成JavaScript:

var  Ile  =  0 ;

即编译器:

  1. 内联枚举(任何用途0,而不是Tristate.False)。
  2. Tristate因为内联用法,所以不会为该枚举定义生成任何JavaScript(运行时没有变量)。

常量枚举preserveConstEnums

内联具有明显的性能优势。Tristate运行时没有变量的事实仅仅是编译器通过不生成运行时实际未使用的JavaScript来帮助您。但是,您可能希望编译器仍然为诸如数字到字符串字符串到数字的查找之类的东西生成枚举定义的JavaScript版本。在这种情况下,您可以使用编译器标志--preserveConstEnums,它仍将生成var Tristate定义,以便您可以在运行时使用Tristate["False"]Tristate[0]手动进行定义。这不会以任何方式影响内联

带有静态函数的枚举

您可以使用声明enumnamespace合并将静态方法添加到枚举。下面演示了一个isBusinessDay向枚举添加静态成员的示例Weekday

enum Weekday {Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
}
namespace Weekday {export function isBusinessDay(day: Weekday) {switch (day) {case Weekday.Saturday:case Weekday.Sunday:return false;default:return true;}}
}const mon = Weekday.Monday;
const sun = Weekday.Sunday;
console.log(Weekday.isBusinessDay(mon)); // true
console.log(Weekday.isBusinessDay(sun)); // false

枚举是开放式的

注意:仅当不使用模块时,开放式枚举才有意义。您应该使用模块。因此,本节最后。

这是为再次显示的枚举生成的JavaScript:

var Tristate;
(function (Tristate) {Tristate[Tristate["False"] = 0] = "False";Tristate[Tristate["True"] = 1] = "True";Tristate[Tristate["Unknown"] = 2] = "Unknown";
})(Tristate || (Tristate = {}));

我们已经解释了该Tristate[Tristate["False"] = 0] = "False";部分。现在注意周围的代码,(function (Tristate) { /*code here */ })(Tristate || (Tristate = {}));特别是该(Tristate || (Tristate = {}));部分。这基本上捕获了一个局部变量TriState,该局部变量将指向一个已定义的Tristate值或使用一个新的空{}对象对其进行初始化。

这意味着您可以跨多个文件拆分(和扩展)枚举定义。例如,下面我们将的定义Color分为两个块

enum Color {Red,Green,Blue
}enum Color {DarkRed = 3,DarkGreen,DarkBlue
}

请注意,您应该(在这里重新初始化第一个成员DarkRed = 3在枚举的延续)来获取生成的代码从以前的定义不会破坏值(即01...等等的值)。无论如何,TypeScript都会警告您(错误消息In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element.)。

翻译来源:https://gitee.com/yunwisdoms/typescript-book/blob/master/docs/enums.md

TypeScript入门教程 之 枚举 Enums相关推荐

  1. 我写的第一本书《TypeScript 入门教程》

    阅读原文 持续了大半年的学习和写作,在今天终于告一段落了. 写书之旅 最初有写书的想法,是刚加入微软的时候. 由于工作中需要重度使用 TypeScript,所以我花了几天的时间研读了好几遍官方手册和中 ...

  2. TypeScript入门教程 之 classes-emit

    TypeScript入门教程 之 classes-emit What's up with the IIFE 为该类生成的js可能是: function Point(x, y) {this.x = x; ...

  3. TypeScript入门教程 之 箭头函数

    TypeScript入门教程 之 箭头函数 亲切地称为粗箭头(因为->是细箭头并且=>是粗箭头),也被称为lambda函数(由于其他语言).另一个常用功能是胖箭头功能()=>some ...

  4. TypeScript入门教程 之 类/抽象类/构造器/Getter/Setter

    TypeScript入门教程 之 类/抽象类/构造器/Getter/Setter 将JavaScript中的类作为头等项很重要的原因是: 类提供了有用的结构抽象 为开发人员提供一种一致的方式来使用类, ...

  5. TypeScript入门教程 之 const

    TypeScript入门教程 之 const const是ES6 / TypeScript提供的非常受欢迎的功能.它使您可以与变量保持不变.从文档以及运行时的角度来看,这都是很好的.要使用const只 ...

  6. TypeScript入门教程 之 解构

    TypeScript入门教程 之 解构 TypeScript支持以下形式的解构(以解构的名义命名,即分解结构): 对象分解 阵列解构 人们很容易将解构视为结构的逆.JavaScript中的结构化方法是 ...

  7. TypeScript入门教程 之 for ... of 与 for ... in

    TypeScript入门教程 之 for ... of 与 for ... in 新手JavaScript开发人员经常遇到的错误是,for...in数组不会遍历数组项.相反,它迭代传入的对象的键.下面 ...

  8. TypeScript入门教程 之 生成器函数

    TypeScript入门教程 之 生成器函数 生成器函数 function *是用于创建生成器函数的语法.调用generator函数将返回一个generator对象.发电机对象如下刚刚所述迭代器接口( ...

  9. 原创 TypeScript入门教程 之  迭代器

    原创 TypeScript入门教程 之 迭代器 Iterator Iterator本身不是TypeScript或ES6功能,Iterator是面向对象的编程语言所通用的行为设计模式.通常,它是一个实现 ...

最新文章

  1. linux共享内存通信方式,linux下进程通信方式--共享内存
  2. 常见Java面试题 – 第二部分:equals与==
  3. 7-48 银行排队问题之单窗口“夹塞”版 (30 分)(思路和详解+map做法)来呀Baby!
  4. Winform开发框架中工作流模块的动态处理
  5. SPQuery如何消除重复记录(实现联动性)
  6. 编译原理教程_3 词法分析
  7. 分享119个Android手机应用源代码总有一个是你想要的
  8. NTKO OFFICE控件帮助文档部分汇总
  9. 3分钟下载好网易云付费音乐
  10. GPGPU基础(五):使用compute shader进行通用计算及示例
  11. SVN中clean up的含义
  12. 判断闰年和平年的程序
  13. iov_iter结构体
  14. adb无线连接不上 解决办法
  15. 【愚公系列】2021年11月 攻防世界-进阶题-MISC-055(肥宅快乐题)
  16. SSMS证书已被颁发者吊销解决办法
  17. Facebook 如何存储150亿张、1.5PB的照片
  18. php录音功能,微信开发之录音功能
  19. Python爬虫实战:京东拍拍验机(帮你买到最完美的二手iPhone)
  20. 我发现,英语,是这辈子都躲不过的事儿

热门文章

  1. [手把手教]discuzX2插件制作教程__最菜鸟级别的入门坎 【二】
  2. Web开发人员应当知道的15个开源项目
  3. cmd命令行启动、停止IIS,打开iis net start w3svc
  4. 如何建立MSSQL数据库
  5. 总结@ 在C# 中的用法
  6. MySQL入门 (四) : JOIN 与UNION 查询
  7. 3个检测浏览器User-Agent信息的网站
  8. TSVD截断奇异值分解
  9. 136.只出现一次的数字
  10. 数据结构---function