一起养成写作习惯!这是我参与「掘金日新计划 · 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 即可, 既可以做到一改全改
枚举会出现在编译结果中
在编译结果中, 相当于创建了一个叫 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"
}
所以需要遍历 数字枚举 时, 需要考虑这个特点。
枚举最佳实践
- 尽量不要在一个枚举中既出现字符创字段, 又出现数字字段。
- 使用枚举时, 尽量使用枚举字段名称, 而不使用真实值。