精进TypeScript--你了解enum(枚举)吗?

TypeScript赞成使用枚举的理由是,比起直接用数字,枚举提供了更多的安全性和透明度。

enum Direction{
	UP = 0,
	DOWN = 1,
	LEFT = 2,
	RIGHT = 3
}
let direction = Direction.UP; // 类型是Direction
Direction // 自动补全显示:UP,DOWN,...
Direction[0] // 值为UP

其实,TypeScript中的枚举有几种不同的变体,它们的行为都有微妙的不同:

  • 数字值的枚举。任何数字都可以分配到这个枚举,所以它不是很安全(数字值枚举可以实现标志位结构)
  • 字符串值的枚举。这个确实提供了类型安全,也在运行时提供了更透明的值。但它不是结构类型化的,不像TypeScript中的任何其他类型。
  • const enum。与普通枚举不同,const enum在运行时完全消失。如果你在前面的例子中改成const enum Direction,编译器会把Direction.UP改写成0。这不但打破了我们对编译器应有行为的期望,而且任然有string和number值枚举之间的分歧行为。
  • 设置了preserveConstEnum标志的const enum。这将为const enum输出运行时代码,就和为普通的enum所做的一样。

字符串值的枚举是名义类型化的,这个是特别出人意料的部分,因为TypeScript中的其他类型的可分配性都用了结构类型来判断。

enum Direction{
	UP = 'up',
	DOWN = 'down',
	LEFT = 'left',
	RIGHT = 'right'
}
let direction = Direction.UP; // 类型是Direction
direction = 'right-up'; // ~~不能将类型'right-up'分配给类型Direction

当要发布一个库的时候,这就会有影响。假设需要一个Direction函数:

function toDirection(direction: Direction) { /*...*/ }

因为运行时的Deirection其实只是一个字符串,所以你的JavaScript用户可以用一个字符串来调用它:

toDirection('up'); // JavaScript中OK

但你的TypeScript用户将需要导入enum来调用它:

toDirection('up'); // ~~'up'不能分配给类型为Direction的参数
import { Direction } from 'direction';
toDirection(Direction.UP); // OK

JavaScript和TypeScript用户的这些体验的不一致性是应避免使用字符串值枚举的原因之一。TypeScript提供了一个在其他语言中不太常见的枚举的替代方案–字面量类型的联合:

type Direction = 'up' | 'down' | 'left' | 'right';

let direction: Direction = 'up'; // OK
direction = 'right-up'; // ~~不能将类型‘right-up’分配给类型Direction

它提供了和枚举一样强大的安全性,并且具有更直接地编译成JavaScript的优势。它也能在你的编译器中提供同样强大的自动补全特性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~卷心菜~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值