在用 TypeScript 写项目的时候,经常会需要定义一些状态类型,这个时候就会纠结:究竟是用枚举(enum)呢,还是用联合类型(union type)呢? 如果你也有类似的困惑,不妨继续往下看,我先说结论吧:
联合类型比枚举好。
那究竟好在什么地方呢?下面详细解释:
简洁
定义联合类型很简洁,只需要一行代码而已:
type Status = "idle" | "pending" | "resolved" | "rejected";
而定义枚举类型比较复杂,一行绝对搞不定,例如:
enum Status {
Idle = "idle",
Pending = "pending",
Resolved = "resolved",
Rejected = "rejected"
}
易扩展
扩展联合类型非常容易,例如:
type Status = "idle" | "pending" | "resolved" | "rejected";
type UserStatus = Status | "existed";
而枚举类型是无法继承和扩展的,你只能再定义一个枚举,把那些值重复写一遍:
enum Status {
Idle = "idle",
Pending = "pending",
Resolved = "resolved",
Rejected = "rejected"
}
enum UserStatus {
Idle = "idle",
Pending = "pending",
Resolved = "resolved",
Rejected = "rejected",
Existed = "existed",
}
无副作用
使用联合类型不仅有类型提示:
type Status = "idle" | "pending" | "resolved" | "rejected";
const status: Status = 'idle'
而且编译出来的代码非常简洁:
var status = 'idle';
再看看用枚举类型做同样的事情:
enum Status {
Idle = "idle",
Pending = "pending",
Resolved = "resolved",
Rejected = "rejected"
}
const status: Status = Status.Idle
编译出来的代码是一大坨,文件体积增加了好几倍:
var Status;
(function (Status) {
Status["Idle"] = "idle";
Status["Pending"] = "pending";
Status["Resolved"] = "resolved";
Status["Rejected"] = "rejected";
})(Status || (Status = {}));
var status = Status.Idle;
类型安全
联合类型使用起来是非常安全的,例如:
type Status = "idle" | "pending" | "resolved" | "rejected";
const updateStatus = (newStatus: Status) => {
console.log(newStatus);
};
updateStatus("idle"); // 只能输入 Status 定义的 4 个字符串,否则报错
而枚举类型是有先天缺陷的,请看:
enum Status {
Idle = "idle",
Pending = "pending",
Resolved = "resolved",
Rejected = "rejected"
};
const updateStatus = (newStatus: Status) => {
console.log(newStatus);
};
updateStatus("idle"); // 这里铁定报错,但 idle 明明是一个枚举范围之内的值啊
updateStatus(Status.Idle); // 只有这样写才行
你也许会说,这样没毛病呀,就是必须指定枚举类型的值,但是你看下面的反人类行为:
enum Status {
Idle = 0,
Pending = 1,
Resolved = 2,
Rejected = 3
};
const updateStatus = (newStatus: Status) => {
console.log(newStatus); // 打印 20
};
updateStatus(20); // 这里竟然不会报错
好了,本文就介绍到这了,我反正是不再用枚举了。至于屏幕面前的读者,随便你啦!写代码,无非就是图个开心嘛!