【问题标题】:Convert array of strings into enum将字符串数组转换为枚举
【发布时间】:2020-11-20 18:33:54
【问题描述】:

说,我有一个数组 const colors = ['R', 'G', 'B'](或对象 const colors = {R: 'R', G: 'G', B: 'B'} 也可以)。如果我没有遗漏任何东西,考虑将打字稿枚举转译成对象。有没有办法将上面的数组(或对象)动态解析成枚举?

例如类似(非工作伪代码示例):

type Color = colors.reduce((palette, color) => palette | color)

enum Color = colors.reduce((palette, color) => (palette[color] = color, palette), enum)

背后的整个想法是将一长串字符串值转换为枚举,而不用硬编码英里长的类型定义,例如:

type Color = 'R' | 'G' | 'B' .. /* followed by gazillion more color values */

【问题讨论】:

    标签: javascript typescript enums


    【解决方案1】:

    我认为你需要这样的东西:

    
    const Colors = ['Red', 'Blue', 'Green'] as const;
    
    type colors = typeof Colors[number] // 'Red' | 'Blue' | 'Green'
    
    

    希望这对你有用:)

    【讨论】:

      【解决方案2】:

      简答:

      只有数字枚举可以有计算成员,但这个表达式的类型是“字符串”。如果您不需要详尽检查,请考虑改用对象字面量。

      长答案:

      很遗憾,你可以做到,但这并不意味着你应该这样做:

      const colors = ['R', 'G', 'B']
      enum Color { }
      
      const result = colors.reduce((acc, elem) => {
          return {
              ...acc,
              [elem]: elem
          }
      }, Color)
      

      在这种情况下,您将失去类型安全性。 TS,无法确定 Color 枚举的类型。

      type O = keyof typeof result // never, TS don't know anymore nothing about this type
      
      enum OkColor{
          R='R',
          G='G',
          B='B'
      }
      
      type O2 = keyof typeof OkColor // 'R' | 'G' | 'B' ---> here TS knows the keys of enum
      

      尽量避免enums。 最好的方法是使用常量对象:

      const colors = {
        R:'R',
        G: 'G',
        B: 'B',
      } as const;
      

      如果您仍想使用枚举,请至少使用 const 关键字。见docs

      const enum X {
        A='A'
      }
      

      以下是将数组安全转换为只读对象的代码:

      const colors = ['R', 'G', 'B'] as const;
      
      
      type ValuesOfArray<T extends ReadonlyArray<any>> = T[number]
      
      type ToObj<K extends string> = {
          [P in K]: P
      }
      
      type ToEnum = ToObj<ValuesOfArray<typeof colors>>
      
      
      const toPseudoEnum = <T extends readonly any[], K extends ValuesOfArray<T>>(arr: T):Readonly<ToObj<K>> => {
          return arr.reduce((acc, elem) => {
              return {
                  ...acc,
                  [elem]: elem
              }
          }, {})
      }
      
      const customEnum = toPseudoEnum(colors); // {R:'R',G:'G',B:'B'}
      

      【讨论】:

        猜你喜欢
        • 2014-09-27
        • 2012-11-30
        • 2010-10-03
        • 1970-01-01
        • 2018-07-07
        • 1970-01-01
        • 2014-03-18
        • 2015-06-10
        相关资源
        最近更新 更多