TypeScript 中的ENUM和联合类型使用上有啥不同?

比如这两个类型

type TypeA = 'cat' | 'dog' | 'fish';

enum TypeB {
    cat,
    dog,
    fish
}

虽然在语法上有所不同,但是都起到了对变量的约定作用,从形式上看联合类型还更加简单。枚举类型是不是没有那么必要了呢?

阅读 3.6k
3 个回答

一般来说联合类型就够用了
但是类型完全是编译期的概念,enum 能导出常量值,在写库的时候就能用到了
比如这样:

enum Foo {
  A = 1,
  B = 2,
}
export class Bar {
  prop1 = Foo.A;
}

一般都会使用 union literal + const assertions 代替enum吧,在我看来 enum 更像是其他语言移植过来的,有汇编时期内味儿。

enum有两个好处吧,一个是语义化,另一个它底层实际上会生成一个object,通过key和value相互映射,也意味着你可以通过key找到value或者通过value找到key,但是这种应用在实际生产中并不多见,也并不靠谱,因为当你有多个key同时指向一个value的时候,很难用value去查找key。

所以也有人拿着它去遍历,在enum的的设计上有一点我真的不太理解:它是用数字类型按顺序的作为默认值,如果中途插入,它的顺序就会改变,那在使用的时候就会产生一些奇怪的magic-number。这种遍历难道不会出问题吗?

楼上说的导出常量值的方式其实用 const assertions 也能够做到:

const Foo = {
  A: 0,
  B: 1,
  C: 2,
} as const; // available in TypeScript 3.4+

Foo.A; // 0

我是觉得联合类型是纯类型,枚举其实算得上是一种数据类型

type TypeA = 'cat' | 'dog' | 'fish';

let a: TypeA = 'cat'
let _a = 'cat' // 只能推断是字符串

enum TypeB {
    cat,
    dog,
    fish
}

let b: TypeB = TypeB.cat
let _b = TypeB.cat // 直接推断是枚举

枚举有一个概念叫“变体”,可以查一下,在做条件判断的时候有一个覆盖性

结论就是不要将枚举看作是类型,把他看成一个变量(上边的常量对象说明的狠好),你会发现枚举更像是一个被冻结的对象,但是你有不需要限定keyof,用变体就相当于直接用值,类型和变量二合一。

描述可能略有比准确,理解为主

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进