Short introdation... Types definition technic in TypeScript:

Click here to share this article on LinkedIn »

Simple class:

var UserType = (function(){

function UserType(){

}

/* some code */

return UserType;

})();

or enumeration:

var UserType;

(function(){

/* other code */

})(UserType || UserType = <type_initializer>);

What do need it anonymous function?:

var typeName = (function(){ ... })();

The TypeScript use self-invoking anonymous functions to create user types after function executing. Him function is return function-builder or set variable where has been received as argument. You can see placed braces`() ` after self-invokeable function. This need to invoke self-invokeable function when him will be meeted.

So… Go to enumeration…

Enumeration is simple object which has object prototype. This is fact! Look…

Naming convention after expiriment:

Object is simple dictionary where:

Enumeration key — object key/object property.

Enumeration value — property value of own object.

Before start, we see what different between classes and enumeration in TypeScript.

TypeScript class definition:

class User {

}

Transpiled to ES5:

var User = (function () {

function User() {

}

return User;

}());

TypeScript a enumeration definition:

enum Names {

}

Transpiled to ES5:

var Names;

(function (Names) {

})(Names || (Names = {}));

We can see that enumeration definition used a own type as argument a self-invoked function him follow time has been modified(added keys:values).

So… Anywhere this is very simple… Need add members…

TypeScript:

/*

You can skip values initialization into enum definition.

TypeScript use it as default enum declaration.

*/

enum Names {

Alex = 0,

Denis = 1

}

ES5:

var Names;

(function (Names) {

Names[Names["Alex"] = 0] = "Alex";

Names[Names["Denis"] = 1] = "Denis";

})(Names || (Names = {}));

So… It more interested… What we see(simplified to steps)?:

/*

No step. Only for example.

This is function will be created at run-time in memory really.

*/

function selfInvokable(enumType) {

step 3: enumType["Alex"] = 0;

step 4: enumType[enumType["Alex"]] = "Alex";

step 5: enumType["Alex"] = 1;

step 6: enumType[enumType["Denis"]] = "Denis";

} step 0: var Names = undefined;

step 1: if(!Names) { Names = {}; }

step 2: selfInvokable(Names);

Now we can enumeration presented as follow object(prototype members has been excluded):

var Names = {

"0":"Alex",

"1":"Denis",

"Alex":0,

"Denis":1

};

Use JSON.stringify()(no serialize prototype) to represent picture on above. And Object.keys() to get keys array of object. Warning! Don’t use for-in construction to get enumeration keys, because she return keys from prototype additionally.

So… May be sometime need be develop helper to work with enums… Do make is!

class EnumHelpers { /**

* No instances guard.

*/

private constructor() { } /**

* Get all keys from enumeration.

*/

public static keys(enumType: object) {

const members = Object.keys(enumType);

return members.filter((x) => Number.isNaN(parseInt(x, 10)))

}

}

No bad… We can get keys from enumeration. Then let develop method to get array of { key, value } objects.

/**

* Get key-value array from enumeration.

*/

public static toKeyValueArray(enumType: object) {

return EnumHelpers.keys(enumType)

.map((key) => {

return { key, value: enumType[key] };

});

}

When method to get values from enumeration type:

/**

* Get values from enumeration.

*/

public static values(enumType: object) {

return EnumHelpers.toKeyValueArray(enumType)

.map((kv) => kv.value);

}

You can found other solution to get keys from enumeration, but they can be incorrect. For example: https://stackoverflow.com/a/18112157.

Problem: enumeration value can be negative.

enum Names {

Alex = 0,

Denis = -1

}

* Sample from stack overflow.

* @see https://stackoverflow.com/a/18112157

*/

function getValues(enumType: object) {

for (var enumMember in enumType) {

var isValueProperty = parseInt(enumMember, 10) >= 0

if (isValueProperty) {

console.log("enum member: ", enumType[enumMember]);

}

}

} /*** Sample from stack overflow.*/function getValues(enumType: object) {for (var enumMember in enumType) {var isValueProperty = parseInt(enumMember, 10) >= 0if (isValueProperty) {console.log("enum member: ", enumType[enumMember]); getValues(Names);

Execution result.

Expected:

Expected result.

Fix: