V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xiaoming1992
V2EX  ›  TypeScript

typescript enum 能合并吗?

  •  
  •   xiaoming1992 · 2020-04-06 18:09:25 +08:00 · 4067 次点击
    这是一个创建于 1472 天前的主题,其中的信息可能已经有所发展或是发生改变。

    segmentfault - typescript 里怎么合并枚举 enum国内有这个问题, 但目前没有答案, stackoverflow 搜关键字没搜到想要的...

    enum Vertical {
    	Up = "up",
        Down = "down"
    }
    
    enum Horizon {
    	Left = "left",
        Right = "right"
    }
    
    // 如果 enum 的值是默认的从零自增的数字
    // 那合并确实会出错, Vertical.Up = 0 = Horizon.Left
    // 可是这儿是字符, 且我手动管理不让其冲突, ts 也不允许吗?
    const Dir = Vertical | Horizon
    
    第 1 条附言  ·  2020-04-07 08:04:11 +08:00
    我就希望能有一个操作能将两者合并,得到合并后的枚举类型(我会手动管理令其不冲突,或者建议 ts 内部使用 Symbol 而非 number),并不是真的想对他们执行“或”操作啊。

    最后一行 ` const Dir = Vertical | Horizon ` 没有这个操作,我知道,这一句只是“伪代码”,表义的,我以为我的变量命名已经够清楚了。。。
    6 条回复    2020-04-07 14:36:16 +08:00
    noe132
        1
    noe132  
       2020-04-06 20:48:54 +08:00   ❤️ 1
    类型和值不要弄混了。

    type Dir = Vertical | Horizon

    let value: Dir
    value = Vertical.Up
    value = Horizon.Left
    himself65
        2
    himself65  
       2020-04-06 22:29:38 +08:00   ❤️ 1
    实际上 enum 就是个 object,楼上说的不完全对

    const Dir = Vertical | Horizon 相当于两个 object 取或

    Enum 也只有类型上的取并集,没有值意义上的取并集

    ```
    enum A {
    a = 1,
    b = 2
    }

    enum B {
    c = 3,
    d = 4
    }

    /*
    (function (A) {
    A[A["a"] = 1] = "a";
    A[A["b"] = 2] = "b";
    })(A || (A = {}));
    var B;
    (function (B) {
    B[B["c"] = 3] = "c";
    B[B["d"] = 4] = "d";
    })(B || (B = {}));
    */

    type C = A | B

    let c: C = A.a // correct
    c = C.a // invalid
    ```
    xiaoming1992
        3
    xiaoming1992  
    OP
       2020-04-07 07:51:05 +08:00 via Android
    @noe132 大哥,我知道值能这么搞,问题是我需要枚举也能支持啊。。。

    @himself65 我并不是需要“或”这么一个操作,只是希望枚举能支持合并啊

    ```
    enum A {
    a = 1,
    b = 2
    }

    enum B {
    c = 3,
    d = 4
    }

    我就希望能有一个操作能将两者合并,得到另一个枚举类型 C

    enum C {
    a = 1,
    b = 2,
    c = 3,
    d = 4,
    }
    ```
    noe132
        4
    noe132  
       2020-04-07 09:43:35 +08:00
    如果
    enum A {
    a = 1
    }

    enum B {
    a = 2
    }

    你希望合并后是什么结果?

    明显怎样合并都是类型不安全的。

    就算不考虑 typescript

    var A = { a: 1 }
    var B = { a: 2 }

    var C = { ...A, ...B }
    var C = { ...B, ...A }

    C 也有至少有 2 种可能的结果,而且还和顺序有关系

    而且,const enum 根本就不存在有 A 这个对象,const enum 在编译时就将所有用到的地方全部替换成值了
    const a = A.a 会被直接编译成 const a = 1

    这种情况你连合并都不可能,因为根本就没有 A 这个对象。A 只是代表一个符号。

    如果你想合并,直接用对象字面量就挺好的
    const A = { a: 1 } as const
    const B = { b: 2 } as const
    const C = { ...A, ...B }
    这样 C 就是你要的东西了,而且类型 typescript 也能推导出来。
    xiaoming1992
        5
    xiaoming1992  
    OP
       2020-04-07 10:22:14 +08:00 via Android
    @noe132 直接用对象字面量倒是个好办法

    ```
    enum A {
    a = 1
    }

    enum B {
    a = 2
    }

    你希望合并后是什么结果?

    报错
    ```
    noe132
        6
    noe132  
       2020-04-07 14:36:16 +08:00 via Android
    去提 issue 或者 pr 吧。我觉得你这个需求基本不会被考虑。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5376 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 07:19 · PVG 15:19 · LAX 00:19 · JFK 03:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.