假设我想确保myKey
中的{ myKey: '' }
仅包含字符串foo
,bar
,baz
,我可以通过两种方式实现此目的。
// with a String Literal Type
type MyKeyType = 'foo' | 'bar' | 'baz';
// or with a String Enum
enum MyKeyType {
FOO = 'foo',
BAR = 'bar',
BAZ = 'baz'
}
我想知道一个人在另一个人身上的利弊在哪里,因为我看起来都是一样的(从我访问例如条件检查的值的方式来看)。
我在TS文档中发现的唯一区别是Enums在运行时是真正的对象,在某些情况下可能是可取的。
答案 0 :(得分:15)
要理解的关键是字符串枚举的值是不透明的。
字符串枚举的预期用例是您不希望其他代码知道或关心支持MyKeyType.FOO
的文字字符串是什么。这意味着您无法将文字字符串 "bar"
传递给接受MyKeyType
的函数 - 您必须写{{1}相反。
答案 1 :(得分:6)
开发时枚举的一个好处是,您可以通过intellisense轻松查看选项列表:
同样,您可以使用重构工具轻松更改枚举值,而不是在任何地方更改字符串。
编辑:在VS 2017和TypeScript> = 3.2.4中,intellisense使用字符串文字类型:
答案 2 :(得分:6)
好吧,在转码后的字符串枚举和文字类型之间存在差异。
比较 Typescript 代码
// with a String Literal Type
type MyKeyType1 = 'foo' | 'bar' | 'baz';
// or with a String Enum
enum MyKeyType2 {
FOO = 'foo',
BAR = 'bar',
BAZ = 'baz'
}
使用编译的JavaScript 代码
// or with a String Enum
var MyKeyType2;
(function (MyKeyType2) {
MyKeyType2["FOO"] = "foo";
MyKeyType2["BAR"] = "bar";
MyKeyType2["BAZ"] = "baz";
})(MyKeyType2 || (MyKeyType2 = {}));
您将看到,没有为字符串文字生成代码。因为Typescripts Transpiler仅在编译时用于类型安全。在运行时,字符串文字会“生成为哑”字符串。文字的定义和用法之间没有引用。
因此,还有第三种替代方法,称为 const枚举
看看这个
// with a String Literal Type
type MyKeyType1 = 'foo' | 'bar' | 'baz';
// or with a String Enum
enum MyKeyType2 {
FOO = 'foo',
BAR = 'bar',
BAZ = 'baz'
}
// or with a Const String Enum
const enum MyKeyType3 {
FOO = 'foo',
BAR = 'bar',
BAZ = 'baz'
}
var a : MyKeyType1 = "bar"
var b: MyKeyType2 = MyKeyType2.BAR
var c: MyKeyType3 = MyKeyType3.BAR
将被移植到
// or with a String Enum
var MyKeyType2;
(function (MyKeyType2) {
MyKeyType2["FOO"] = "foo";
MyKeyType2["BAR"] = "bar";
MyKeyType2["BAZ"] = "baz";
})(MyKeyType2 || (MyKeyType2 = {}));
var a = "bar";
var b = MyKeyType2.BAR;
var c = "bar" /* BAR */;
要进一步播放,您可以查看此link
我更喜欢使用const枚举,因为键入Enum.Value的便捷方式。在转译时,Typescript会为我完成其余工作,以使性能最高。
答案 3 :(得分:1)
枚举的一大缺点是,如果您使用数字而不是字符串,在我看来,整个枚举并不安全:我总是可以为此类变量分配任何数字值
enum TYPE {MAN = 1, WOMAN = 2, BOY = 3, GIRL = 4};
let foo: TYPE = TYPE.MAN;
foo = 37.14; //no problem for compiler
答案 4 :(得分:0)
使用枚举代替字符串文字的一个好处是,您也可以在未声明类型的地方使用它。
例如 -
assert.equal(result.keyType, KeyType.FOO)