5、认真学习枚举类型

news2024/9/20 13:46:46

1、数字枚举

// 这里你的TSLint可能会报一个:枚举声明只能与命名空间或其他枚举声明合并。这样的错误,这个不影响编译
enum Status {
  Uploading,
  Success,
  Failed
}
console.log(Status.Uploading); // 0
console.log(Status["Success"]); // 1
console.log(Status.Failed); // 2

        我们使用enum关键字定义了一个枚举值 Status,它包含三个字段,每个字段间用逗号隔开。我们使用枚举值的元素值时,就像访问对象的属性一样,你可以使用’.‘操作符和’[]'两种形式访问里面的值,这和对象一样。

        再来看输出的结果,Status.Uploading 是 0,Status['Success']是 1,Status.Failed 是 2,我们在定义枚举 Status 的时候,并没有指定索引号,是因为这是默认的编号,我们也可以自己指定:

// 修改起始编号
enum Color {
  Red = 2,
  Blue,
  Yellow
}
console.log(Color.Red, Color.Blue, Color.Yellow); // 2 3 4
// 指定任意字段的索引值
enum Status {
  Success = 200,
  NotFound = 404,
  Error = 500
}
console.log(Status.Success, Status.NotFound, Status.Error); // 200 404 500
// 指定部分字段,其他使用默认递增索引
enum Status {
  Ok = 200,
  Created,
  Accepted,
  BadRequest = 400,
  Unauthorized
}
console.log(Status.Created, Status.Accepted, Status.Unauthorized); // 201 202 401

        数字枚举在定义值的时候,可以使用计算值和常量。但是要注意,如果某个字段使用了计算值或常量,那么该字段后面紧接着的字段必须设置初始值,这里不能使用默认的递增值了,来看例子:

const getValue = () => {
  return 0;
};
enum ErrorIndex {
  a = getValue(),
  b, // error 枚举成员必须具有初始化的值
  c
}
enum RightIndex {
  a = getValue(),
  b = 1,
  c
}
const Start = 1;
enum Index {
  a = Start,
  b, // error 枚举成员必须具有初始化的值
  c
}

2、反向映射

        我们定义一个枚举值的时候,可以通过 Enum[‘key’]或者 Enum.key 的形式获取到对应的值 value。TypeScript 还支持反向映射,但是反向映射只支持数字枚举,我们后面要讲的字符串枚举是不支持的。来看下反向映射的例子:

enum Status {
  Success = 200,
  NotFound = 404,
  Error = 500
}
console.log(Status["Success"]); // 200
console.log(Status[200]); // 'Success'
console.log(Status[Status["Success"]]); // 'Success'

        TypeScript 中定义的枚举,编译之后其实是对象,我们来看下上面这个例子中的枚举值 Status 编译后的样子:

我们可以直接使用tsc指定某个文件或者不指定文件直接编译整个目录,运行后就会产生相应的编译后的JavaScript文件,你也可以到TypeScript官方文档提供的在线练习场,在这里你可以编写TypeScript代码,它会同步进行编译。实时编译为JavaScript代码,是你了解编译后结果的好方式。

{
    200: "Success",
    404: "NotFound",
    500: "Error",
    Error: 500,
    NotFound: 404,
    Success: 200
}

        可以看到,TypeScript 会把我们定义的枚举值的字段名分别作为对象的属性名和值,把枚举值的字段值分别作为对象的值和属性名,同时添加到对象中。这样我们既可以通过枚举值的字段名得到值,也可以通过枚举值的值得到字段名。

3、字符串枚举

        TypeScript2.4 版本新增了字符串枚举,字符串枚举值要求每个字段的值都必须是字符串字面量,或者是该枚举值中另一个字符串枚举成员,先来看个简单例子:

enum Message {
  Error = "Sorry, error",
  Success = "Hoho, success"
}
console.log(Message.Error); // 'Sorry, error'

再来看我们使用枚举值中其他枚举成员的例子:

enum Message {
  Error = "error message",
  ServerError = Error,
  ClientError = Error
}
console.log(Message.Error); // 'error message'
console.log(Message.ServerError); // 'error message'

        注意,这里的其他枚举成员指的是同一个枚举值中的枚举成员,因为字符串枚举不能使用常量或者计算值,所以也不能使用其他枚举值中的成员。

4、异构枚举

简单来说异构枚举就是枚举值中成员值既有数字类型又有字符串类型,如下:

enum Result {
  Faild = 0,
  Success = "Success"
}

        但是这种如果不是真的需要,不建议使用。因为往往我们将一类值整理为一个枚举值的时候,它们的特点是相似的。比如我们在做接口请求时的返回状态码,如果是状态码都是数值,如果是提示信息,都是字符串,所以在使用枚举的时候,往往是可以避免使用异构枚举的,重点是做好类型的整理。

5、枚举成员类型和联合枚举类型

        如果枚举值里所有成员的值都是字面量类型的值,那么这个枚举的每个成员和枚举值本身都可以作为类型来使用,先来看下满足条件的枚举成员的值有哪些:

  • 不带初始值的枚举成员,例如enum E { A }
  • 值为字符串字面量,例如enum E { A = ‘a’ }
  • 值为数值字面量,或者带有-符号的数值字面量,例如enum E { A = 1 }enum E { A = -1 }

        当我们的枚举值的所有成员的值都是上面这三种情况的时候,枚举值和成员就可以作为类型来用:

5.1、枚举成员类型

        我们可以把符合条件的枚举值的成员作为类型来使用,来看例子:

enum Animal {
  Dog = 1,
  Cat = 2
}
interface Dog {
  type: Animal.Dog; // 这里使用Animal.Dog作为类型,指定接口Dog的必须有一个type字段,且类型为Animal.Dog
}
interface Cat {
  type: Animal.Cat; // 这里同上
}
let cat1: Cat = {
  type: Animal.Dog // error [ts] 不能将类型“Animal.Dog”分配给类型“Animal.Cat”
};
let dog: Dog = {
  type: Animal.Dog
};

5.2、联合枚举类型

        当我们的枚举值符合条件时,这个枚举值就可以看做是一个包含所有成员的联合类型,先来看例子:

enum Status {
  Off,
  On
}
interface Light {
  status: Status;
}
enum Animal {
  Dog = 1,
  Cat = 2
}
const light1: Light = {
  status: Animal.Dog // error 不能将类型“Animal.Dog”分配给类型“Status”
};
const light2: Light = {
  status: Status.Off
};
const light3: Light = {
  status: Status.On
};

        上面例子定义接口 Light 的 status 字段的类型为枚举值 Status,那么此时 status 的属性值必须为 Status.Off 和 Status.On 中的一个,也就是相当于status: Status.Off | Status.On

6、运行时的枚举

        枚举在编译成 JavaScript 之后实际是一个对象。这个我们前面讲过了,既然是对象,那么就可以当成对象来使用,我们来看个例子:

enum E {
  A,
  B
}
const getIndex = (enumObj: { A: number }): number => {
  return enumObj.A;
};
console.log(getIndex(E)); // 0

        上面这个例子要求 getIndex 的参数为一个对象,且必须包含一个属性名为’A’的属性,其值为数值类型,只要有这个属性即可。当我们调用这个函数,把枚举值 E 作为实参传入是可以的,因为它在运行的时候是一个对象,包含’A’这个属性,因为它在运行的时候相当于下面这个对象:

{
    0: "A",
    1: "B",
    A: 0,
    B: 1
}

7、const enum

        我们定义了枚举值之后,编译成 JavaScript 的代码会创建一个对应的对象,这个对象我们可以在程序运行的时候使用。但是如果我们使用枚举只是为了让程序可读性好,并不需要编译后的对象呢?这样会增加一些编译后的代码量。所以 TypeScript 在 1.4 新增 const enum*(完全嵌入的枚举)*,在之前讲的定义枚举的语句之前加上const关键字,这样编译后的代码不会创建这个对象,只是会从枚举里拿到相应的值进行替换,来看我们下面的定义:

enum Status {
  Off,
  On
}
const enum Animal {
  Dog,
  Cat
}
const status = Status.On;
const animal = Animal.Dog;

上面的例子编译成 JavaScript 之后是这样的:

var Status;
(function(Status) {
  Status[(Status["Off"] = 0)] = "Off";
  Status[(Status["On"] = 1)] = "On";
})(Status || (Status = {}));
var status = Status.On;
var animal = 0; /* Dog */

        我们来看下 Status 的处理,先是定义一个变量 Status,然后定义一个立即执行函数,在函数内给 Status 添加对应属性,首先Status[“Off”] = 0 是给Status对象设置Off属性,并且值设为 0,这个赋值表达式的返回值是等号右边的值,也就是 0,所以Status[Status[“Off”] = 0] = "Off" 相当于Status[0] = “Off”。创建了这个对象之后,将 Status 的 On 属性值赋值给 status;再来看下 animal 的处理,我们看到编译后的代码并没有像Status创建一个Animal对象,而是直接把Animal.Dog的值0替换到了const animal = Animal.Dog表达式的Animal.Dog位置,这就是const enum的用法了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/459327.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智能骨传导蓝牙耳机该如何选,分享几款不错的骨传导蓝牙耳机

骨传导耳机是一种通过骨骼传递声音的耳机。相比于传统的耳塞和头戴式耳机,它有许多优点,例如: 1.安全。因为无需通过耳膜进行声音传递,所以对听力影响较小。 2.对耳朵没有伤害。 3.舒适。 4.节省时间。由于无需通过耳膜传递声音&a…

Codefi基于区块链的开发框架

💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! Codefi基于区块链的开发框架 Codefi技术是一种基于区块链的开发框架,它提供了一系列工具和服务,帮助开发者轻松构建和管理去中心化应用程序。C…

【Access】win 10 / win 11:Access 下载、安装、使用教程(「管理信息系统」实践专用软件)

目录 一、前言 二、卸载 Office 三、下载 Office Tool Plus 四、安装 Office(内含 Access) (1)启动 Office Tool Plus (2)部署 (3)安装 Office(内含 Access&#…

C++STL详解(10) -- 使用哈希表封装unordered_set和unordered_map

文章目录 哈希表模板参数改造针对模板参数V改造增加仿函数获取具体数据类型. 哈希表的正向迭代器正向迭代器中的内置成员:正向迭代器的成员函数 哈希表插入函数的修改(适用于unordered_map)一个类型K去做set和unordered_set他的模板参数的必备条件.unordered_set的模拟实现(完整…

看完这篇文章你就彻底懂啦{保姆级讲解}-----(LeetCode刷题242有效的字母异位词) 2023.4.25

目录 前言算法题(LeetCode刷题242有效的字母异位词)—(保姆级别讲解)分析题目:有效的字母异位词代码:算法思想: 结束语 前言 本文章一部分内容参考于《代码随想录》----如有侵权请联系作者删除…

详解js跨页面传参以及API的解释

详解js跨页面传参 前言什么是跨页面传参?跨页面传参本质是什么?常见的跨页面传参方法URL参数传递localStorage和sessionStorage参数传递Cookie传递 经常听到API,那么到底的什么是API? 前几天有粉丝私信我,希望能把js跨…

超越YOLOv8,飞桨推出精度最高的实时检测器RT-DETR!

‍‍ 众所周知,实时目标检测( Real-Time Object Detection )一直由 YOLO 系列模型主导。 飞桨在去年 3 月份推出了高精度通用目标检测模型 PP-YOLOE ,同年在 PP-YOLOE 的基础上提出了 PP-YOLOE 。后者在训练收敛速度、下游任务泛化能力以及高性能部署能力…

搞懂 API ,地图 API 制作方法分享

地图 API 是一种基于 Web 开发的应用程序编程接口,可以用于创建和展示地图及地理信息。以下是一些地图 API 制作的方法: 选择地图 API 平台:目前市场上有很多地图 API 平台供选择,比如 Google Maps API、百度地图 API、高德地图 A…

Chess.com:象棋社区网站每月访问量达 2.8 亿,年收入在 5000 万至 1 亿之间

Chess.com是世界领先的国际象棋社区。它始于 2007 年,目前年收入超过 5000 万美元。 核心功能 Live Chess 花了 5 个多月才发布。到那时,该网站已经拥有近100,000名会员。Chess.com 域名的重要性他们 80% 的用户来自过去 4 年 Chess.com的故事是如何开…

[算法前沿]--004-transformer的前世今生

文章目录 1.transformer介绍1.1 注意力机制1.2 Transformer架构1.2.1编码器1.2.2解码器 2. Transformer中的模块2.1 注意模块2.1.1 缩放点积注意事项2.1.2 多头注意 2.2 Transformer中的注意事项2.2.1 自注意2.2.2 掩蔽的自注意(自回归或因果注意)2.2.3 …

027:Mapbox GL加载circle样式图层,用data-driven风格绘制圆形

第027个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中加载circle样式图层。圆形样式图层在地图上呈现一个或多个实心圆。 您可以使用圆形图层来配置矢量切片中点或点集合要素的视觉外观。 圆形层渲染其半径以屏幕单位测量的圆形。 直接复制下面的 vue+mapbox源…

HTML5 <label> 标签、HTML5 <map> 标签

HTML5 <label> 标签 实例 HTML5 <label>标签用于为 input 元素做出标记。 带有两个输入字段和相关标记的简单 HTML 表单&#xff1a; <form action"demo_form.asp"><label for"male">Male</label><input type"ra…

【libuv】入门:queue work 的跨线程异步通信

通过阅读2012年的uv book 入门。有中文版 Handles and Requests libuv works by the user expressing interest in particular events. This is usually done by creating a handle to an I/O device, timer or process. Handles are opaque structs named as uv_TYPE_t where…

【分布式搜索引擎ES01】

分布式搜索引擎ES 分布式搜索引擎ES1.elasticsearch概念1.1.ES起源1.2.倒排索引1.2.1.正向索引1.2.2.倒排索引 1.3.es的一些概念1.3.1.文档和字段1.3.2.索引和映射1.3.3.mysql与elasticsearch 1.4.1安装es、kibana、IK分词器1.4.2扩展词词典与停用词词典 2.索引库操作2.1.mappi…

设置网格旋转轴心【Babylonjs】

推荐&#xff1a;用 NSDT场景设计器 快速搭建3D场景。 Babylon.js 中的轴心&#xff08;Pivot Point&#xff09;是使用父节点设置网格变换中心的替代方法&#xff0c;即用作旋转中心或放大中心的点。 注意&#xff1a;使用 setPivotPoint 产生的行为不同于在 3DS Max 和 Maya …

vue-cli的使用和单页面应用程序、使用vue-cli脚手架创建vue项目步骤

1.vue-cli的使用 vue-cli是Vue.js开发的标准工具。它简化了程序员基于webpack创建工程化的Vue项目的过程。 引用自vue-cli官网上的一句话: 程序员可以专注在撰写应用上&#xff0c;而不必花好几天去纠结webpack配置的问题。 中文官网: https://cli.vuejs.org/zh/ 1.1 安装 …

WTI纽约原油CFD是什么?交易技巧有哪些?

WTI常称为美国原油或纽约原油&#xff0c;WTI是West Texas Intermediate 的简称&#xff0c;代表西德州中级原油(West Texas Intermediate)&#xff0c;偶尔称为德州轻甜原油(Texas Light Sweet)&#xff0c;它是大宗商品交易中核心的石油基准。那么本文就来具体的聊聊&#xf…

接口自动化【四】(在接口自动化【三】上的优化_加入了类前置,表格中替换数据,断言)

前言 一、使用 unittest框架结合setUpClass前置条件上传图片 二、一个类里面同时有类方法和实例方法----补充知识点&#xff08;需要引用类方法中的变量&#xff09; 三、结合类前置setUpClass&#xff0c;ddt&#xff0c;Excel表格数据&#xff0c;进行上传图片 四、加入l…

铁路应答器传输系统介绍

应答器传输系统 应答器传输系统是安全点式信息传输系统&#xff0c;通过应答器实现地面设备向车载设备传输信息。 应答器可根据应用需求向车载设备传输固定的&#xff08;通过无源应答器&#xff09;或可变的&#xff08;通过有源应答器&#xff09;上行链路数据。 当天线单…

【gitee】安装依赖报错

gitee地址 安装依赖时报错 Error while executing: npm ERR! D:\gongju\Git\cmd\git.EXE ls-remote -h -t git://github.com/adobe-web npm ERR! Error while executing: npm ERR! D:\git\Git\cmd\git.EXE ls-remote -h -t https://github.com/nhn/raphael.git npm ERR! npm…