Gol*_*Age 9 enums typescript ecmascript-6
我想知道如何在TypeScript中向枚举添加描述属性。我想创建如下的枚举(或类似的东西):
public enum Sample
{
[Display(Name = "Blah V")]
V,
[Display(Name = " Blah IV")]
IV,
[Display(Name = " Blah III")]
III,
}
Run Code Online (Sandbox Code Playgroud)
为了能够对此类枚举执行基本操作,我将创建通用的EnumHelper。该帮助器类应包含允许使用的方法:获取描述值,获取名称和数字值。问题是如何在打字稿中实现这一点?如果无法向枚举添加属性,有什么办法吗?我希望能够:
- get number of enum value,
- get description value,
- get the name of enum field.
Run Code Online (Sandbox Code Playgroud)
例如对于Sample.IV它将是:
1,
Blah IV,
IV.
Run Code Online (Sandbox Code Playgroud)
man*_*h_s 18
下面的方法将是类型安全的(自动完成工作)并且它使用普通对象。它基于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",
};
Run Code Online (Sandbox Code Playgroud)
man*_*nza 17
在此处建立的另一个有趣的解决方案是使用ES6 Map:
export enum Sample {
V,
IV,
III
}
export const SampleLabel = new Map<number, string>([
[Sample.V, 'FIVE'],
[Sample.IV, 'FOUR'],
[Sample.III, 'THREE']
]);
Run Code Online (Sandbox Code Playgroud)
使用
console.log(SampleLabel.get(Sample.IV)); // FOUR
Run Code Online (Sandbox Code Playgroud)
小智 7
已接受答案的变体。替换number为您的enum类型以提高类型安全性。
export enum Sample {
V,
IV,
III
}
export const SampleLabel = new Map<Sample, string>([
[Sample.V, 'FIVE'],
[Sample.IV, 'FOUR'],
[Sample.III, 'THREE']
]);
Run Code Online (Sandbox Code Playgroud)
TypeScript 不允许您向enum元素添加属性,它在运行时只是一个原始字符串或数字。相反,你必须做一些事情,比如创建一个新类型,它保存对这些元素的引用,并且还拥有你想要的方法或属性。
这是一种可能的方法。enum像这样从你的平原开始:
enum SampleEnum {
V, IV, III
}
Run Code Online (Sandbox Code Playgroud)
让我们为您的扩展类型提供一个接口定义。它有一个name、一个description和一个number。请注意,此类型是通用的,因此我们可以很快缩小name和number类型的范围:
interface ISample<N extends number, S extends string> {
readonly name: S;
readonly description: string;
readonly number: N;
}
Run Code Online (Sandbox Code Playgroud)
这是一个函数,它可以获取您的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;
}
Run Code Online (Sandbox Code Playgroud)
这可能是很多类型的杂耍,但它基本上只是从中提取字符串值键SampleEnum(并忽略在运行时将数字键添加到数字枚举的反向映射)并为每个扩展接口构建一个实例,在一个有点类型安全的方式。
最后,让我们创建Sample代表我们的值和类型enum:
const Sample = makeSample(SampleEnum);
type Sample = (typeof Sample)[keyof typeof Sample]
Run Code Online (Sandbox Code Playgroud)
好的,让我们使用它:
const nameOfIV = Sample.IV.name; // "IV"
console.log(nameOfIV); // "IV"
const numberOfIII = Sample.III.number; // SampleEnum.III
console.log(numberOfIII); // 1
const descriptionOfV = Sample.V.description; // string
console.log(descriptionOfV); // "Blah V"
const goodSample: Sample = Sample.III; // okay
const badSample: Sample = {
name: "II",
description: "oops",
number: 3
}; // error, name doesn't match
Run Code Online (Sandbox Code Playgroud)
对我来说看起来很合理。 自己看看。当然,还有其他方法可以解决它,但这应该会给你一个想法。希望有帮助。祝你好运!
这种模式对我有用:
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
}
Run Code Online (Sandbox Code Playgroud)
...
GetDescription(e: any, id: number): string {
return e[e[id].toString() + "Description"];
}
getPriceTypeDescription(price: IPricePoint): string {
return this.GetDescription(PriceTypes, price.priceType);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4520 次 |
| 最近记录: |