【问题标题】:enum type gives double array in typescript枚举类型在打字稿中给出双数组
【发布时间】:2018-03-06 06:29:11
【问题描述】:

我想从枚举数据类型创建一个下拉列表,但是当我尝试将枚举更改为具有名称和值的对象时;枚举数组返回枚举成员的两倍。使用来自this SO post的函数

  • 打字稿:v 2.3.3

  • Angular v 4.3.4

ps。由于角度版本,无法更新打字稿版本。下面是相关代码

export enum FrequencyEnum {
    H1 = <any>'1 Hour',
    H12 = <any>'12 Hours',
    D1 = <any>'24 Hours',
    D7 = <any>'7 Days',
    M1 = <any>'1 Month',
    M3 = <any>'3 Months',
    CD = <any>'Custom Date Range'
};
export interface Frequency {
    name: string;
    value: string;
    range?: { from: string; to: string; };
}

export function enumSelector(definition) {
    console.log('definition: ', definition);
    return Object.keys(definition)
        .map(key => ({ value: definition[key], name: key }));
}

this.frequnecyList = enumSelector(FrequencyEnum);

它给出了 14 个对象的数组

[
  {
    "value": "1 Hour",
    "name": "H1"
  },
  {
    "value": "H1",
    "name": "1 Hour"
  },
  {
    "value": "12 Hours",
    "name": "H12"
  },
  {
    "value": "H12",
    "name": "12 Hours"
  },
  {
    "value": "24 Hours",
    "name": "D1"
  },
  {
    "value": "D1",
    "name": "24 Hours"
  },
  {
    "value": "7 Days",
    "name": "D7"
  },
  {
    "value": "D7",
    "name": "7 Days"
  },
  {
    "value": "1 Month",
    "name": "M1"
  },
  {
    "value": "M1",
    "name": "1 Month"
  },
  {
    "value": "3 Months",
    "name": "M3"
  },
  {
    "value": "M3",
    "name": "3 Months"
  },
  {
    "value": "Custom Date Range",
    "name": "CD"
  },
  {
    "value": "CD",
    "name": "Custom Date Range"
  }
]

如何才能在最终数组中只获得 7 个值(等于枚举成员)?

【问题讨论】:

    标签: typescript enums


    【解决方案1】:

    恐怕由于 TypeScript 实现枚举的方式,这不太可能。如果您查看为您的枚举生成的 JavaScript 代码,您会看到:

    var FrequencyEnum;
    (function (FrequencyEnum) {
        FrequencyEnum[FrequencyEnum["H1"] = '1 Hour'] = "H1";
        FrequencyEnum[FrequencyEnum["H12"] = '12 Hours'] = "H12";
        FrequencyEnum[FrequencyEnum["D1"] = '24 Hours'] = "D1";
        FrequencyEnum[FrequencyEnum["D7"] = '7 Days'] = "D7";
        FrequencyEnum[FrequencyEnum["M1"] = '1 Month'] = "M1";
        FrequencyEnum[FrequencyEnum["M3"] = '3 Months'] = "M3";
        FrequencyEnum[FrequencyEnum["CD"] = 'Custom Date Range'] = "CD";
    })(FrequencyEnum || (FrequencyEnum = {}));
    ;
    

    JavaScript 中的赋值表达式返回其正确的值,这意味着 FrequencyEnum["H1"] = '1 Hour' 的计算结果为 1 Hour,并在结果对象中有效地为您提供了一个值为 "H1" 的属性 '1 Hour'。这就是为什么您会看到值也显示为键,因此键/值的大小是您期望的两倍。

    您可以做一个技巧,过滤掉列表中的每个偶数键,但这不是一个非常可靠的解决方案:

    export function enumSelector(definition: any) {
        return Object.keys(FrequencyEnum)
                     .filter((key, i) => i % 2 == 0)
                     .map(key => ({ value: definition[key], name: key }))
    }
    

    这将为您提供输出:

    [ { value: '1 Hour', name: 'H1' },
      { value: '12 Hours', name: 'H12' },
      { value: '24 Hours', name: 'D1' },
      { value: '7 Days', name: 'D7' },
      { value: '1 Month', name: 'M1' },
      { value: '3 Months', name: 'M3' },
      { value: 'Custom Date Range', name: 'CD' } ]
    

    另一个(更好的)解决方案是不使用枚举,而是简单地使用对象文字而不是枚举:

    const FrequencyEnum = {
        H1: '1 Hour',
        H12: '12 Hours',
        D1: '24 Hours',
        D7: '7 Days',
        M1: '1 Month',
        M3: '3 Months',
        CD: 'Custom Date Range'
    };
    

    【讨论】:

    • 是的,我采用了同样的方法。感谢您的解决方案。
    • 您的意思是使用对象文字而不是枚举?如果您对它感到满意,也请接受答案:-)
    • 是对象文字而不是枚举。还有另一种使用 npm 包 enum-string 的方法,但方法很长
    猜你喜欢
    • 2021-10-03
    • 2017-03-09
    • 2019-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-06
    • 2020-04-30
    • 2019-09-25
    相关资源
    最近更新 更多