我可以问一下在 Typescript(和字符串联合类型)中使用(或不使用)枚举的任何哲学原因吗?
Can I ask any philosophical reason for using (or not using) enum in Typescript (and string union type)
这几天学习了Typescript中enum
和const enum
的概念,一头雾水。我知道 const enum
将被转换为简单值,而另一个则不会。我还了解到使用字符串联合类型和普通 enum
(如迭代)之间的一些功能差异。
但我无法理解何时以及为什么我应该(不)使用(const
)enum
。我认为 enum
上的迭代不是那么普遍,很难预测他们是否会使用它。
有一个 post(这是用韩语写的,很抱歉)“tree-shaking 无法优化转译 enum
,因为它们是 IIFE”。 (Link)
我应该毫不犹豫地使用 const enum
,还是使用其他替代方法有更多的优点和缺点:字符串联合类型。
TLDR
- 如果
const enum
比 enum
更轻量级,是否有使用 enum
的实际理由?
- 我已经知道
Babel
不能与 const enum
一起工作。在那种情况下,为什么有人使用 enum
而不是字符串联合类型,即使他们不对其进行迭代。
我相信 enums
从 C#
来到 TypeScript。
一般来说,TypeScript 中的数值 enums
是不安全的。考虑这个例子:
const enum Foo{
a,
b
}
const handle=(arg:Foo)=>arg
handle(42) // no error
这是因为 TypeScript 具有结构类型系统而不是名义上的。
非 const enum
会产生大量样板代码:
var Foo;
(function (Foo) {
Foo[Foo["a"] = 0] = "a";
Foo[Foo["b"] = 1] = "b";
})(Foo || (Foo = {}));
所以,我的建议是完全避免 enums
。您可以改用不可变对象。考虑这个例子:
const Foo = {
a: 1,
b: 2
} as const;
type Values<T> = T[keyof T]
type Foo = Values<typeof Foo>;
const handle = (arg: Foo) => arg
handle(Foo.a) // ok
handle(Foo.b) // ok
handle(42) // error
至于string unions
,想象一下这种情况:
enum Events {
click = 'click',
hover = 'hover'
}
type Union = 'click' | 'hover'
您在 100 个文件中使用 Events.click
作为值,然后您的技术主管告诉您应该将 click
重命名为 _click
。
你接下来要做什么:
enum Events {
click = '_click',
hover = '_hover'
}
就是这样。您只需更改一个类型声明,而在联合字符串的情况下,您需要替换每个使用的文字字符串。这只是一个案例。我相信联合字符串有很多用例。假设您有一些需要使用字符串文字的类型。没有理由只创建一个运行时值来表示一个类型。这是使用字符串文字而不是 enums
.
的有效情况
这一切都取决于。
这几天学习了Typescript中enum
和const enum
的概念,一头雾水。我知道 const enum
将被转换为简单值,而另一个则不会。我还了解到使用字符串联合类型和普通 enum
(如迭代)之间的一些功能差异。
但我无法理解何时以及为什么我应该(不)使用(const
)enum
。我认为 enum
上的迭代不是那么普遍,很难预测他们是否会使用它。
有一个 post(这是用韩语写的,很抱歉)“tree-shaking 无法优化转译 enum
,因为它们是 IIFE”。 (Link)
我应该毫不犹豫地使用 const enum
,还是使用其他替代方法有更多的优点和缺点:字符串联合类型。
TLDR
- 如果
const enum
比enum
更轻量级,是否有使用enum
的实际理由? - 我已经知道
Babel
不能与const enum
一起工作。在那种情况下,为什么有人使用enum
而不是字符串联合类型,即使他们不对其进行迭代。
我相信 enums
从 C#
来到 TypeScript。
一般来说,TypeScript 中的数值 enums
是不安全的。考虑这个例子:
const enum Foo{
a,
b
}
const handle=(arg:Foo)=>arg
handle(42) // no error
这是因为 TypeScript 具有结构类型系统而不是名义上的。
非 const enum
会产生大量样板代码:
var Foo;
(function (Foo) {
Foo[Foo["a"] = 0] = "a";
Foo[Foo["b"] = 1] = "b";
})(Foo || (Foo = {}));
所以,我的建议是完全避免 enums
。您可以改用不可变对象。考虑这个例子:
const Foo = {
a: 1,
b: 2
} as const;
type Values<T> = T[keyof T]
type Foo = Values<typeof Foo>;
const handle = (arg: Foo) => arg
handle(Foo.a) // ok
handle(Foo.b) // ok
handle(42) // error
至于string unions
,想象一下这种情况:
enum Events {
click = 'click',
hover = 'hover'
}
type Union = 'click' | 'hover'
您在 100 个文件中使用 Events.click
作为值,然后您的技术主管告诉您应该将 click
重命名为 _click
。
你接下来要做什么:
enum Events {
click = '_click',
hover = '_hover'
}
就是这样。您只需更改一个类型声明,而在联合字符串的情况下,您需要替换每个使用的文字字符串。这只是一个案例。我相信联合字符串有很多用例。假设您有一些需要使用字符串文字的类型。没有理由只创建一个运行时值来表示一个类型。这是使用字符串文字而不是 enums
.
这一切都取决于。