LoginSignup
9
6

More than 3 years have passed since last update.

TypeScript EnumにvalueOfメソッドを実装する

Posted at

TypeScriptのEnum(列挙型)にはvalueOf(文字列から対応するenum要素を取得する)メソッドが用意されていないため、実装を追加する方法を調査した。なお、Enumには任意のメソッドを追加できないため、namespaceを利用して実装している。

Numeric Enum

自動インクリメントされた数値が割り当てられる数値型(Numeric)Enumでは、逆引きマップ(Reverse Mapping)が利用できるため、Enum[string] でvalueOf相当の処理を実現できる。ただし、そのままでは型エラー(Element implicitly has an 'any' type...)となるため、以下のいずれかの記述とする必要がある。

  • Enum[string as keyof typeof Enum]
  • (<any>Enum)[string]
実装例
/* 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)Enumでは、Reverse Mappingが利用できない(※)ため、自分で逆引き用のMapオブジェクトを用意する必要がある。

実装例
/* 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

※ Numeric Enumと同様にEnumのキー名からEnumを取得することはできるが、Enumに割り当てた文字列からEnumを取得することはできない。

let str = 'Green'
Color[str as keyof typeof Color]; // => Color.Green
str = 'green'
Color[str as keyof typeof Color]; // => undefined
参考
9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6