将描述属性添加到枚举并在TypeScript

时间:2018-06-10 13:57:42

标签: typescript ecmascript-6 enums

我想知道如何在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.

6 个答案:

答案 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
}

让我们为您的扩展类型提供接口定义。它有namedescriptionnumber。请注意,此类型是通用的,因此我们可以尽快缩小namenumber类型的范围:

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]

这将返回-已批准。

Ref link