How typescript implements enumerations?

I was wondering about how typescript would compile an enumeration into a javascript code. So I implemented the following example:

enum Contagens {
    UM,
    DOIS,
    TRES
}

And it was compiled into this:

"use strict";
var Contagens;
(function (Contagens) {
    Contagens[Contagens["UM"] = 0] = "UM";
    Contagens[Contagens["DOIS"] = 1] = "DOIS";
    Contagens[Contagens["TRES"] = 2] = "TRES";
})(Contagens || (Contagens = {}));

But, I don’t understand how it works… someone could explain this code to me?

Answer

  1. The variable var Contagens; This creates the variable that will hold a reference to the enum.

  2. The argument Contagens || (Contagens = {}) the enum is used if it already exists, and will be set to an empty object, if it doesn’t. This allows enums to be extended:

enum Contagens {
    UM,
    DOIS,
    TRES
}

enum Contagens {
    CATRE = 4
}
  1. The function function (Contagens) { takes an argument Contagens that is the value from step #2. In this function it will create the entries on the enum object. It has the same name as the outer variable Contagens, so it shadows that variable. But it’s the same value, so that doesn’t matter much.

  2. The assignment.

Contagens[Contagens["UM"] = 0] = "UM";

The result of an assignment is the value being assigned.* So Contagens["UM"] = 0 does two things. It sets the key "UM" to the value 0, and it returns 0.

That returned 0 is used then in the a second assignment:

Contagens[0] = "UM";

Now the "UM" property has been assigned 0 and the 0 property has been assigned to "UM". The enum now looks like this:

{ UM: 0, "0": "UM" }

This allows you to lookup a value in an enum by its name, or get its name from its value.

Contagens.UM // 0
Contagens[0] // "UM"

Which is handy!


* The result of an assignment when delcaring a variable is undefined, but assigning a property of an object or assigning to an existing variable will return the assigned value. JS is quirky like that.