DEV Community

loading...

[TypeScript] Implement valueOf method in Enums

unhurried
・2 min read

Enums in Typescript don't have valueOf method, which returns an enum element from its string representation. This article explains how we can add valueOf method to Enums. Note that the implementation suggested in this article uses namespace as we cannot add arbitrary methods to Enums.

Numeric Enum

Numeric Enums, which assign incremental numbers to their elements, support reverse mapping . Therefore valueOf method can be implemented with Enum[string].

However we need to use one of the following expressions as Enum[string] produces a type error which says "Element implicitly has an 'any' type...".

  • Enum[string as keyof typeof Enum]
  • (<any>Enum)[string]
Implementation Example
/* Numeric Enum */
enum Color { Red, Green };

// toString()
Color.Green.toString(); // => '1'
Color[Color.Green]; // => 'Green'

// valueOf()
namespace Color {
  export function valueOf(str: string) {
    return Color[str as keyof typeof Color];
  }
}
const str = 'Green';
Color.valueOf(str); // => NumericEnum.Green
String Enum

String Enums, to which we can assign arbitrary string representations to their elements, don't support reverse mapping (*). Therefore we need to prepare a map object for reverse mapping by ourselves.

Implementation Example
/* String Enum */
enum Color { Red = 'red', Green = 'green' };

// toString()
Color.Green.toString(); // => 'green'

// valueOf()
namespace Color {
  const reverseMap = new Map<string, Color>();
  Object.keys(Color).forEach((s: string) => {
    const e = (<any>Color)[s];
    reverseMap.set(e.toString(), e);
  });
  export function valueOf(str: string) {
    return reverseMap.get(str);
  }
}
const str = 'green';
Color.valueOf(str); // => StringEnum.Green

* Enum elements can be retrieved by their key names just like numeric enums, but not by strings that are assigned to enum elements.

let str = 'Green'
Color[str as keyof typeof Color]; // => Color.Green
str = 'green'
Color[str as keyof typeof Color]; // => undefined
Reference

Discussion (0)