如何在TypeScript中合并两个枚举 [英] How to merge two enums in TypeScript

查看:2216
本文介绍了如何在TypeScript中合并两个枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有下面的Typescript中描述的两个枚举,然后如何合并它们

Suppose I have two enums as described below in Typescript, then How do I merge them

enum Mammals {
    Humans,
    Bats,
    Dolphins
}

enum Reptiles {
    Snakes,
    Alligators,
    Lizards
}

export default Mammals & Reptiles // For Illustration purpose, Consider both the Enums have been merged.

现在,当我在另一个文件中import exported value时,我应该能够从两个枚举中访问值.

Now, when I import the exported value in another file, I should be able to access values from both the enums.

import animalTypes from "./animalTypes"

animalTypes.Humans //valid

animalTypes.Snakes // valid

如何在Typescript中实现这种功能?

How can I achieve such functionality in Typescript?

推荐答案

合并问题:

  • 相同的值=>值被覆盖
  • 相同键=>键被覆盖

    Problems with the merge:

    • same values => values are overwritten
    • same keys => keys are overwritten

      ❌具有相同值的枚举(=>值被覆盖)

      ❌ Enums with same values (=> values are overwritten)

      enum AA1 {
        aKey, // = 0
        bKey // = 1
      }
      enum BB1 {
        cKey, // = 0
        dKey // = 1
      }
      

      • ❌具有相同键的枚举(=>键被覆盖)
      • enum AA2 {
          aKey = 1
        }
        enum BB2 {
          aKey = 2
        }
        

        • ✅好
        • enum AA3 {
            aKey, // = 0
            bKey // = 1
          }
          enum BB3 {
            cKey = 2,
            dKey // = 3
          }
          

          • ✅也很好
          • enum AA4 {
              aKey = 'Hello',
              bKey = 0,
              cKey // = 1
            }
            enum BB4 {
              dKey = 2,
              eKey = 'Hello',
              fKey = 'World'
            }
            

            注意: aKey = 'Hello'eKey = 'Hello'之所以起作用,是因为带有字符串值的枚举没有将此值作为键

            Note: aKey = 'Hello' and eKey = 'Hello' work because the enum with a string value doesn't has this value as key

            // For aKey = 'Hello', key is working
            type aa4aKey = AA4.aKey; // = AA4.aKey
            // value is not.
            type aa4aValue = AA4.Hello; // ❌ Namespace 'AA4' has no exported member 'Hello'
            type aa4aValue2 = AA4['Hello']; // ❌ Property 'Hello' does not exist on type 'AA4'
            
            console.log(AA4); // { 0: 'bKey', 1: 'cKey', aKey: 'Hello', bKey: 0, cKey: 1 }
            console.log(BB4); // { 2: 'dKey', dKey: 2, eKey: 'Hello', fKey: 'World' }
            

            合并

            • ❌使用联合类型
            • type AABB1 = AA4 | BB4; // = AA4 | BB4
              type AABB1key = AABB1['aKey']; // = never
              type AABB1key2 = AABB1.aKey; // ❌ 'AABB1' only refers to a type, but is being used as a namespace here. ts(2702)
              

              • ❌使用交叉点类型
              • type AABB1 = AA4 & BB4; // = never
                type AABB1key = AABB1['aKey']; // = never
                

                • ✅使用具有typeof的交点类型
                • type AABB2 = (typeof AA4) & (typeof BB4); // = typeof AA4 & typeof BB4
                  type AABB2key = AABB2['aKey']; // = AA4.aKey
                  

                  • ✅使用js复制
                  • const aabb1 = { ...AA4, ...BB4 };
                    const aabb2 = Object.assign({}, AA4, BB4); // also work
                    // aabb1 = {
                    // 0: 'bKey',
                    // 1: 'cKey',
                    // 2: 'dKey',
                    // aKey: 'Hello',
                    // bKey: 0,
                    // cKey: 1,
                    // dKey: 2,
                    // eKey: 'Hello',
                    // fKey: 'World' }
                    

                    • ✅使用typeof和js副本
                    • const aabb = { ...AA4, ...BB4 };
                      type TypeofAABB = typeof aabb;
                      // type TypeofAABB = {
                      // [x: number]: string;
                      // dKey: BB4.dKey;
                      // eKey: BB4.eKey;
                      // fKey: BB4.fKey;
                      // aKey: AA4.aKey;
                      // bKey: AA4.bKey;
                      // cKey: AA4.cKey;
                      // };
                      

                      提示:您可以为类型和值使用相同的名称

                      Tip: you can use the same name for a type and a value

                      const merged = { ...AA4, ...BB4 };
                      type merged = typeof merged;
                      
                      const aValue = merged.aKey;
                      type aType = merged['aKey'];
                      

                      您的案子

                      如果要合并2个枚举,则有〜3个选择:

                      Your case

                      If you want to merge your 2 enums you have ~3 choices:

                      enum Mammals {
                        Humans = 'Humans',
                        Bats = 'Bats',
                        Dolphins = 'Dolphins'
                      }
                      
                      enum Reptiles {
                        Snakes = 'Snakes',
                        Alligators = 'Alligators',
                        Lizards = 'Lizards'
                      }
                      
                      export const Animals = { ...Mammals, ...Reptiles };
                      export type Animals = typeof Animals;
                      

                      2.使用唯一数字

                      enum Mammals {
                        Humans = 0,
                        Bats,
                        Dolphins
                      }
                      
                      enum Reptiles {
                        Snakes = 2,
                        Alligators,
                        Lizards
                      }
                      
                      export const Animals = { ...Mammals, ...Reptiles };
                      export type Animals = typeof Animals;
                      

                      3.使用嵌套枚举

                      enum Mammals {
                        Humans,
                        Bats,
                        Dolphins
                      }
                      
                      enum Reptiles {
                        Snakes,
                        Alligators,
                        Lizards
                      }
                      
                      export const Animals = { Mammals, Reptiles };
                      export type Animals = typeof Animals;
                      
                      const bats = Animals.Mammals.Bats; // = 1
                      const alligators = Animals.Reptiles.Alligators; // = 1
                      

                      注意:您还可以将嵌套枚举与以下代码合并.如果这样做,请注意不要有重复的值!

                      Note: you can also merge the nested enums with the following code. Take care to NOT have duplicated values if you do that!

                      type Animal = {
                        [K in keyof Animals]: {
                          [K2 in keyof Animals[K]]: Animals[K][K2]
                        }[keyof Animals[K]]
                      }[keyof Animals];
                      
                      const animal: Animal = 0 as any;
                      
                      switch (animal) {
                        case Animals.Mammals.Bats:
                        case Animals.Mammals.Dolphins:
                        case Animals.Mammals.Humans:
                        case Animals.Reptiles.Alligators:
                        case Animals.Reptiles.Lizards:
                        case Animals.Reptiles.Snakes:
                          break;
                        default: {
                          const invalid: never = animal; // no error
                        }
                      }
                      

                      这篇关于如何在TypeScript中合并两个枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆