【问题标题】:Using enums as types allows values that don't exist in the enum使用枚举作为类型允许枚举中不存在的值
【发布时间】:2018-03-09 09:07:50
【问题描述】:

我有这个打字稿代码 (typescript playground):

const enum Something {
  None = 0,
  Email = 10,
  All = 20
}

const enum Other{
  Email = 10;
  Value = 15;
}

interface Foo {
  prop: Something
}
const value2: Something = Something.None;

// Why can 15 be assigned if it's not in the enum?
const value: Something = 15;

// This errors:
const otherValue: Something = 'asdf';

const value3: Something = Something.NotExists;

const value4: Something = Other.Value;

const value5: Something = Other.Email;

我不明白为什么在这种情况下 15 是一个可接受的值。 15 不是枚举的值,所以不应该抛出吗?

【问题讨论】:

标签: typescript enums


【解决方案1】:

(2021-06-10更新,the TS4.3 update for union enums未更改)

这是(可能令人惊讶的)预期行为。 TypeScript 中的数字枚举有时用于按位运算,其中列出的值被视为flags。并且,正如@RyanCavanaughcommentreported issue 中所述:

我们不区分标志和非标志枚举,因此大于[或不等于]任何给定枚举成员的数字不一定是无效的。例如

enum Flags { Neat = 1, Cool = 2, Great = 4 } // like saying Neat | Cool | Great var x: Flags = 7;

因此,即使7 不等于列出的Flags 枚举值中的任何一个,您仍然可以通过对列出的值执行按位运算来获得它。我很确定编译器除了检查该值是否为number 之外,不会做任何 限制。

在您的情况下,即使Something 枚举值都不是15,但它不会阻止您执行以下(无用且可疑的理智):

const value: Something = (Something.Email | Something.All) >> 1;

相当于同一件事(10 | 20 的计算结果为 3030 >> 115)。


请注意,这种按位运算不适用于 基于字符串的 枚举,因此解决此问题的一种方法是将数字更改为字符串文字:

const enum Something {
  None = '0',
  Email = '10',
  All = '20'
}
const value: Something = '15'; // error, as desired

编译器会警告您'15' 不是Something 的有效值。

希望对您有所帮助。祝你好运!

【讨论】:

    猜你喜欢
    • 2020-08-05
    • 2012-11-14
    • 1970-01-01
    • 1970-01-01
    • 2012-11-05
    • 1970-01-01
    • 2018-10-18
    • 1970-01-01
    相关资源
    最近更新 更多