将TypeScript枚举转换为对象数组
将TypeScript枚举转换为对象数组
我定义了一个枚举,如下所示:
export enum GoalProgressMeasurements { Percentage = 1, Numeric_Target = 2, Completed_Tasks = 3, Average_Milestone_Progress = 4, Not_Measured = 5 }
然而,我希望它以以下方式表示为API中的对象数组/列表:
[{id: 1, name: 'Percentage'}, {id: 2, name: 'Numeric Target'}, {id: 3, name: 'Completed Tasks'}, {id: 4, name: 'Average Milestone Progress'}, {id: 5, name: 'Not Measured'}]
是否有一种简单而本地的方法可以实现这一点,还是我必须构建一个函数,将枚举转换为整数和字符串,并将对象构建成数组?
问题的出现原因是在TypeScript中,枚举类型是在运行时存在的真实对象。因此,我们可以通过反向映射来实现将枚举值转换为对应的名称。解决方法是通过遍历枚举类型的属性,筛选出数值类型的属性,并将其转换为对象数组。
根据以上内容,我们可以使用以下代码来解决问题:
export enum GoalProgressMeasurements { Percentage = 1, Numeric_Target = 2, Completed_Tasks = 3, Average_Milestone_Progress = 4, Not_Measured = 5 } let map: {id: number; name: string}[] = []; for(var n in GoalProgressMeasurements) { if (typeof GoalProgressMeasurements[n] === 'number') { map.push({id:GoalProgressMeasurements[n], name: n}); } } console.log(map);
执行以上代码后,将会输出枚举类型的对象数组。
需要注意的是,上述方法不适用于字符串值的枚举类型。
参考链接:[https://www.typescriptlang.org/docs/handbook/enums.html](https://www.typescriptlang.org/docs/handbook/enums.html)
需要注意的是,默认情况下,枚举类型的值从1开始自动递增。因此,在代码中的枚举类型的定义中,我们可以省略对应的默认值,只需要写到目标值即可。
虽然可以省略默认值,但是在代码中明确写出来更加清晰易懂,因此更推荐这样做。
问题的出现是因为在使用TypeScript的枚举类型时,希望将枚举转换成对象数组的形式。然而,原始的解决方法只适用于ES8版本,并且只适用于纯数字类型的枚举。对于包含字符串值的异构枚举,原始的解决方法无法正常工作。
解决方法是使用TypeScript v5的新特性。在TypeScript v5中,可以使用Object.entries
方法将枚举转换成对象数组的形式。下面是解决方法的示例代码:
enum Colors { WHITE = 0, BLACK = 1, BLUE = 3 } const colorObjectArray = Object.entries(Colors).map(([key, value]) => ({ key, value }));
这样,colorObjectArray
将会是一个对象数组,其中包含了枚举的键和值。对于上述示例,colorObjectArray
将会是[{ key: 'WHITE', value: 0 }, { key: 'BLACK', value: 1 }, { key: 'BLUE', value: 3 }]
。
使用Object.entries
方法可以确保枚举的键和值都能正确地转换成对象数组的形式,无论枚举是纯数字类型还是异构类型。这样,就能够更方便地对枚举进行处理和操作。
需要注意的是,本文提到的解决方法仅适用于TypeScript v5及以上版本。如果使用的是较旧版本的TypeScript,则需要使用其他方法来将枚举转换成对象数组的形式。
TypeScript枚举(enum)在转换为对象数组时会出现一些问题。具体来说,TypeScript会将枚举对象进行"双重映射",以便可以通过键和值进行访问。例如,一个枚举对象MyEnum:
enum MyEnum {
Part1 = 0,
Part2 = 1
}
在转换为对象数组时,会被转换为:
{
Part1: 0,
Part2: 1,
0: 'Part1',
1: 'Part2'
}
这种转换方式会导致枚举对象中的键值对翻倍。因此,在进行映射之前,应该先对对象进行过滤。下面是一个正确的实现示例:
// Helper
const StringIsNumber = value => isNaN(Number(value)) === false;
// 将枚举转换为数组
function ToArray(enumme) {
return Object.keys(enumme)
.filter(StringIsNumber)
.map(key => enumme[key]);
}
可以这样使用:
export enum GoalProgressMeasurements {
Percentage,
Numeric_Target,
Completed_Tasks,
Average_Milestone_Progress,
Not_Measured
}
console.log(ToArray(GoalProgressMeasurements));
在以上讨论中,某些情况下在控制台中使用Object.values(MyEnum)只打印出0和1,而不是期望的["Part1", "Part2", 0, 1]。这可能是因为使用了不同的TypeScript版本或者使用了字符串枚举。根据官方文档的说明,字符串枚举不会生成反向映射。在这个例子中使用的是数字枚举而不是字符串枚举。
需要注意的是,以上实现方法可能无法处理类似'1e5' = 1这样的特殊情况。不过,这种情况属于极端情况,通常不会出现。