TypeScript入门教程 之 枚举 Enums

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,     // 0
    Green,   // 1
    Blue     // 2
}

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

enum Color {
    DarkRed = 3,  // 3
    DarkGreen,    // 4
    DarkBlue      // 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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你想学习 TypeScript,我推荐你查看引用中提到的一篇入门教程。这篇教程将带你一步步学习 TypeScript 的十四个入门知识点,并且提供了详细的内容大纲。教程会教你如何在系统中全局安装 TypeScript,可以使用 npm 或者 yarn 进行安装。TypeScript 是 JavaScript 的超集,它在 JavaScript 的基础上添加了可选的静态类型和基于类的面向对象编程特性。微软在 2012 年正式发布了 TypeScript,并且持续更新和维护了 8 年。因此学习 TypeScript 是非常有价值的,尤其对于前端开发人员来说,它已经成为一门必备的技能。所以如果你想学习 TypeScript,这个入门教程会是一个不错的起点。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [最全TypeScript 入门基础教程,看完就会](https://blog.csdn.net/qq_43623970/article/details/107067306)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [TypeScript入门教程](https://blog.csdn.net/SoSalty/article/details/129372440)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值