代码之家  ›  专栏  ›  技术社区  ›  Narretz

使用枚举作为类型允许枚举中不存在的值

  •  5
  • Narretz  · 技术社区  · 7 年前

    我有这个打字脚本代码( 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在这个caase中是一个可接受的值。15不是枚举的值,所以它不应该抛出吗?

    1 回复  |  直到 7 年前
        1
  •  5
  •   jcalz    3 年前

    (更新日期:2021 06月10日,未更改为 the TS4.3 update for union enums )

    这是(可能令人惊讶的)预期行为。TypeScript中的数字枚举有时用于按位操作,其中列出的值被视为 flags 。以及 @RyanCavanaugh 在a中 comment reported 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 计算结果为 30 30 >> 1 15 )。


    请注意,此按位内容不适用于 基于字符串 枚举,因此处理此问题的一种方法是将数字更改为字符串文字:

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

    编译器会警告您 '15' 不是的有效值 某物

    希望这有帮助。祝你好运