How do I create nested enums in Typescript

Solution 1:

You can't add methods that are callable on enum members in TypeScript. Although it's disappointing (in an object-oriented sense), the practical solution usually used is external static utility functions which switch on the enum and handle all cases.

You can attach static methods to the enum, which is a convenient way to group and keep track of the utility functions that help you work with the enum "metadata".

You can implement an enum-style pattern that allows for methods callable on enum members. But these are not first-class TypeScript enums, though in most cases they are a sufficient replacement. It does feel disappointing to abandon the built-in enum for something that you cook up yourself, but this is a pattern that people do use.

The current technical reason is that the value attached to each enum key is a string literal, which has no common prototype shared by only the key values of the enum. Given this TypeScript:

enum MyEnum {
    A='A',
    B='B'
}

The JavaScript code generated is:

var MyEnum;
(function (MyEnum) {
    MyEnum["A"] = "A";
    MyEnum["B"] = "B";
})(MyEnum || (MyEnum = {}));

As you can see there is no common prototype or class for the member values, so we cannot "hack" our way into adding functions the member values unless we extend the global String class itself, which is a Bad Idea. TypeScript would need to complicate the design of enums by wrapping the member value strings in a second class with a common prototype (or at least a common interface -- express or implied), and I guess the language designers didn't want to introduce that level of complexity.