2、TS 中的扩展类型(枚举)

985 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

上文将了 基本类型 , 今天来说说 TS 的扩展类型。

枚举

枚举通常约束某一个变量的取值范围。

字面量和联合类型配合使用, 也可以达到 枚举 的目的

分析二者的区别, 为什么要使用枚举?

字面量类型的问题

在类型约束的地方会产生重复的代码。

举个栗子

let sex: '男' | '女'
sex = '男'
sex = '女'

此时有一个查询用户接口, 需要传递查询的性别

function searchUsers(sex: '男' | '女'){}

也许会有人会说 不是有 类型别名 么: type Sex = '男'| '女' 这的确可以解决问题

类型别名 只适用于解决这个问题, 但下面的问题 类型别名 就不太好解决

逻辑含义和真实的值产生了混淆, 会导致当修改真实值的时候, 会产生大量的修改。

举个栗子

type Sex = '男'| '女'
let sex: Sex
sex = '男'
sex = '女'
function searchUsers(sex: Sex){}

将来有一天你的产品经理突然抽搐, 叫你把性别改为 'man' | 'woman' 此时就不敢修改 Sex 这个类型的约束, 因为不知道在那些地方使用过这个类型。

字面量类型不会进入到编译结果。

某些场景下 需要动态的使用 ts 中定义的某些值, 使用 字面量类型 定义, 是不会存在编译结果里面的。

解决方案 --- 枚举

枚举可以描述为 自己定义的类型

如何定义一个枚举

语法:

enum 枚举名 {
    枚举字段 = 值,
    枚举字段 = 值
}

举个栗子

enum Genter {
    man = '男',
    woman = '女'
}

let sex: Genter

接下来对 sex 赋值就不会直接赋值真是的值, 而是使用逻辑值

sex = Genter.man
sex = Genter.woman

以后想使用新的值, 只需要改变 Genter 即可, 既可以做到一改全改

枚举会出现在编译结果中

image.png

在编译结果中, 相当于创建了一个叫 Genter 的对象。

正因于此, 就可以在 ts 书写下面这样的代码, 来打印枚举的值

enum Genter {
    man = "男",
    woman = '女'
}

function printEnum(data: object) {
    const keys = Object.keys(data);
    for (const key of keys) {
        console.log(data[key])
    }
}

printEnum(Genter)

枚举注意点

枚举的字段值可以是 数字或者字符串

enum Level {
    Level1 = 1,
    Level2 = 2
}

数字枚举

枚举字段值为数字的称之为 数字枚举, 它有一下特点。

  • 数字的值会自动递增
enum Level {
    Level1 = 1,
    Level2,
    Level3,
    Level4,
}

此时 Level2,Level3,Level4 的值分别为 2、3、4

如果 level1 不复制, 那么它们默认重 0 开始递增.

  • 被数字枚举的变量可以直接赋值
enum Level {
    Level1,
    Level2,
    Level3,
}

const level:Level = 1; 

这在 ts 中是合法的, 但是这里就存在隐患了,不推荐使用

  • 数字枚举的编译结果和字符串有差异
// 编译结果
var Level;
(function (Level) {
    Level[Level["Level1"] = 0] = "Level1";
    Level[Level["Level2"] = 1] = "Level2";
    Level[Level["Level3"] = 2] = "Level3";
})(Level || (Level = {}));
const level = 1;

这个 Level 实际是这个样子

var Level = {
    Level1: 0,
    Level2: 1,
    Level3: 2,
    0: "Level1",
    1: "Level2",
    2: "Level3"
}

所以需要遍历 数字枚举 时, 需要考虑这个特点。

枚举最佳实践

  • 尽量不要在一个枚举中既出现字符创字段, 又出现数字字段。
  • 使用枚举时, 尽量使用枚举字段名称, 而不使用真实值。