Home > Enterprise >  Proper way to cast an enum to Type in Typescript
Proper way to cast an enum to Type in Typescript

Time:09-02

I have an angular enum like this:

export enum ProtectiveClassificationType
{
  InflationAdjustedNominal =1,
  NominalInflationAdjusted =2,
  InflationAdjusted =3,
  Nominal =4,
  None = 5
}

and 2 methods. One to get the description of an enum item and the other one to return the enum as a <key, value> pair to use it into select lists:

export interface SelectPayload {
 key: string | number;
 value: string;
}

  protected enumToList(type: Type, nameResolver: (element: number) => string): SelectPayload[] {
        const retList: SelectPayload[] = [];
        const values = Object.values(type);
        for (const value of values.slice(values.length / 2))
        retList.push({ key: value, value: nameResolver(value) });
        return retList;
    }//enumToList


  public getProtectiveClassificationByType(type: number): string {
    switch (type) {
      case ProtectiveClassificationType.InflationAdjusted: return "Inflation Adjusted";
      case ProtectiveClassificationType.InflationAdjustedNominal: return "Inflation Adjusted then Nominal";
      case ProtectiveClassificationType.Nominal: return "Nominal";
      case ProtectiveClassificationType.NominalInflationAdjusted: return "Nominal then Inflation Adjusted";
      case ProtectiveClassificationType.None: return "None";
      default: return "Unknown";
    }
  }

  public  getProtectiveClassificationTypeToList(): SelectPayload[] {       
    return this.enumToList(ProtectiveClassificationType as unknown as Type, this.getProtectiveClassificationByType.bind(this));      
  }//getProtectiveClassificationTypeToList

The method enumToList is from a base class and in order to use it I have to do such a cast ProtectiveClassificationType as unknown as Type. For me it doesn't look right and now my question is if there is a better way to do it. PS: "Type" is from "import { Type } from "typescript";

CodePudding user response:

Explanation

Your solution is the only one that will work without making changes to enumToList function, because import { Type } from "typescript" doesn't overlap with enum.

ProtectiveClassificationType as unknown as Type

Refactoring Solution

This involves changing the enumToList method to use generics, then later when you use the function, don't specify the type in the generics, however your linter may complain. Although, this solution is the equivalent to using any which removes the type safety but then again, so does forcing the type of the enum to be Type when they don't overlap.

protected enumToList<T>(enum: T, nameResolver: (element: number) => string): SelectPayload[] {
      const retList: SelectPayload[] = [];
      const values = Object.values(enum);
      for (const value of values.slice(values.length / 2))
      retList.push({ key: value, value: nameResolver(value) });
      return retList;
  }//enumToList

...

public getProtectiveClassificationTypeToList(): SelectPayload[] {       
  return this.enumToList(ProtectiveClassificationType, this.getProtectiveClassificationByType.bind(this));      
}//getProtectiveClassificationTypeToList
  • Related