TypeScript中枚举转换为Type类型的正确实现方式
优化Angular枚举转选择列表的类型转换问题
问题背景
现有代码中,基类的enumToList方法参数使用了typescript的Type类型,导致传入自定义枚举ProtectiveClassificationType时必须通过as unknown as Type强制类型转换,写法冗余且不符合类型安全原则。
优化方案
方案1:修改基类enumToList的参数类型(推荐)
Type是TypeScript用于表示类型元数据的工具类型,并不适合描述枚举对象。我们可以将基类方法改为接受泛型枚举对象,同时过滤出枚举的数值项(避免反向映射的字符串键):
// 基类中修改后的enumToList方法 protected enumToList<T extends Record<string, number | string>>( enumObj: T, nameResolver: (element: T[keyof T]) => string ): SelectPayload[] { const retList: SelectPayload[] = []; // 过滤出枚举的数值类型值,排除反向映射的字符串键 const enumValues = Object.values(enumObj).filter(v => typeof v === 'number') as T[keyof T][]; for (const value of enumValues) { retList.push({ key: value, value: nameResolver(value) }); } return retList; }
修改后调用时无需任何类型转换,直接传入枚举即可:
public getProtectiveClassificationTypeToList(): SelectPayload[] { return this.enumToList(ProtectiveClassificationType, this.getProtectiveClassificationByType.bind(this)); }
方案2:无法修改基类时的适配方案
如果基类无法修改,可以在子类中新增适配方法,先处理枚举对象再传入基类方法,避免直接强制转换:
// 子类中新增适配方法 private adaptEnumToList( enumObj: Record<string, number>, nameResolver: (element: number) => string ): SelectPayload[] { // 先提取枚举的数值项,再构造适配结构 const enumValues = Object.values(enumObj).filter(v => typeof v === 'number'); return this.enumToList(enumObj as unknown as Type, nameResolver); } // 调用适配方法 public getProtectiveClassificationTypeToList(): SelectPayload[] { return this.adaptEnumToList(ProtectiveClassificationType, this.getProtectiveClassificationByType.bind(this)); }
额外优化:简化枚举描述映射
可以将switch case替换为映射对象,让代码更简洁易维护:
private readonly protectiveClassificationLabels: Record<ProtectiveClassificationType, string> = { [ProtectiveClassificationType.InflationAdjusted]: "Inflation Adjusted", [ProtectiveClassificationType.InflationAdjustedNominal]: "Inflation Adjusted then Nominal", [ProtectiveClassificationType.Nominal]: "Nominal", [ProtectiveClassificationType.NominalInflationAdjusted]: "Nominal then Inflation Adjusted", [ProtectiveClassificationType.None]: "None" }; public getProtectiveClassificationByType(type: number): string { return this.protectiveClassificationLabels[type as ProtectiveClassificationType] || "Unknown"; }
内容的提问来源于stack exchange,提问作者D A
相关产品推荐
相关产品推荐

