TS

时间:2018-04-10 19:58:47

标签: typescript

假设我想确保myKey中的{ myKey: '' }仅包含字符串foobarbaz,我可以通过两种方式实现此目的。

   // 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在运行时是真正的对象,在某些情况下可能是可取的。

5 个答案:

答案 0 :(得分:15)

要理解的关键是字符串枚举的值是不透明的

字符串枚举的预期用例是您不希望其他代码知道或关心支持MyKeyType.FOO的文字字符串是什么。这意味着您无法将文字字符串 "bar"传递给接受MyKeyType的函数 - 您必须写{{1}相反。

答案 1 :(得分:6)

开发时枚举的一个好处是,您可以通过intellisense轻松查看选项列表:

enter image description here

同样,您可以使用重构工具轻松更改枚举值,而不是在任何地方更改字符串。

编辑:在VS 2017和TypeScript> = 3.2.4中,intellisense使用字符串文字类型:

enter image description here

答案 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)