我想知道如何在TypeScript中向enum添加描述属性。 我想创建枚举如下(或类似的东西):
public enum Sample
{
[Display(Name = "Blah V")]
V,
[Display(Name = " Blah IV")]
IV,
[Display(Name = " Blah III")]
III,
}
为了能够对这样的枚举进行基本操作,我将创建通用的EnumHelper。此辅助类应包含允许以下方法:获取描述值,获取名称和数值。问题是如何在打字稿中实现这一目标?如果无法向枚举添加属性,有什么办法吗? 我希望能够:
- get number of enum value,
- get description value,
- get the name of enum field.
e.g。对于Sample.IV,它将是:
1,
Blah IV,
IV.
答案 0 :(得分:7)
另一个有趣的解决方案founded here使用的是ES6 Map:
max
使用
export enum Sample {
V,
IV,
III
}
export const SampleLabel = new Map<number, string>([
[Sample.V, 'FIVE'],
[Sample.IV, 'FOUR'],
[Sample.III, 'THREE']
]);
答案 1 :(得分:4)
此模式对我有用:
export enum PriceTypes {
Undefined = 0,
UndefinedDescription = 'Undefined' as any,
UserEntered = 1,
UserEnteredDescription = 'User Entered' as any,
GeneratedFromTrade = 2,
GeneratedFromTradeDescription = 'Generated From Trade' as any,
GeneratedFromFreeze = 3,
GeneratedFromFreezeDescription = 'Generated Rom Freeze' as any
}
...
GetDescription(e: any, id: number): string {
return e[e[id].toString() + "Description"];
}
getPriceTypeDescription(price: IPricePoint): string {
return this.GetDescription(PriceTypes, price.priceType);
}
答案 2 :(得分:3)
TypeScript不允许您向enum
元素添加属性,该元素在运行时只是一个原始字符串或数字。相反,你必须做一些事情,比如创建一个新类型,它保存对这些元素的引用,并且还有你想要的方法或属性。
这是一种可行的方法。从您的普通enum
开始:
enum SampleEnum {
V, IV, III
}
让我们为您的扩展类型提供接口定义。它有name
,description
和number
。请注意,此类型是通用的,因此我们可以尽快缩小name
和number
类型的范围:
interface ISample<N extends number, S extends string> {
readonly name: S;
readonly description: string;
readonly number: N;
}
这是一个函数,可以使用SampleEnum
对象并返回具有相同键但具有实现扩展接口的值的内容:
function makeSample<E extends Record<Extract<keyof E, string>, number>>(
mapping: E
): { [K in Extract<keyof E, string>]: ISample<E[K], K> } {
const ret = {} as { [K in Extract<keyof E, string>]: ISample<E[K], K> };
(Object.keys(mapping).filter(k => k !== (+k) + "") as
(Extract<keyof E, string>)[]
).forEach(k => {
ret[k] = {
name: k,
description: "Blah " + k,
number: mapping[k]
}
});
return ret;
}
这可能是很多类型杂耍,但它基本上只是从SampleEnum
中提取字符串值的键(并忽略在运行时向数字枚举添加数字键的reverse mapping并以某种类型安全的方式为每一个构建扩展接口的实例。
最后,让我们创建代表我们Sample
的{{1}}值和类型:
enum
好的,让我们使用它:
const Sample = makeSample(SampleEnum);
type Sample = (typeof Sample)[keyof typeof Sample]
对我来说很合理。 See for yourself。当然还有其他方法来处理它,但这应该有希望给你一个想法。希望有所帮助。祝你好运!
答案 3 :(得分:1)
已接受答案的变体。将number
替换为您的enum
类型,以确保类型更安全。
export enum Sample {
V,
IV,
III
}
export const SampleLabel = new Map<Sample, string>([
[Sample.V, 'FIVE'],
[Sample.IV, 'FOUR'],
[Sample.III, 'THREE']
]);
答案 4 :(得分:1)
以下方法将是安全类型(自动完成工作),并且使用普通对象。它基于this feature of TypeScript。
export enum Sample {
I = 1,
II = 2,
III = 3
}
export const SampleLabel: { [key in Sample]: string } = {
[Sample.I]: "ONE",
[Sample.II]: "TWO",
[Sample.III]: "THREE",
};
答案 5 :(得分:0)
enum Status {
New = 0,
Progress = 1,
Approved = 2,
Rejected = 3
}
我们可以使用反向映射获得如下描述:
Status[2]
这将返回-已批准。