TypeScript

9     Enums

An enum type is a distinct subtype of the Number primitive type with an associated set of named constants that define the possible values of the enum type.

9.1    Enum Declarations

An enum declaration declares an enum type and an enum object in the containing module.

EnumDeclaration:
enum   Identifier   {   EnumBodyopt   }

The enum type and enum object declared by an EnumDeclaration both have the name given by the Identifier of the declaration. The enum type is a distinct subtype of the Number primitive type. The enum object is a variable of an anonymous object type containing a set of properties, all of the enum type, corresponding to the values declared for the enum type in the body of the declaration. The enum object’s type furthermore includes a numeric index signature with the signature ‘[x: number]: string’.

The Identifier of an enum declaration may not be one of the predefined type names (section 3.6.1).

The example

enum Color { Red, Green, Blue }

declares a subtype of the Number primitive type called ‘Color’ and introduces a variable ‘Color’ with a type that corresponds to the declaration

var Color: {
    [x: number]: string;
    Red: Color;
    Green: Color;
    Blue: Color;
};

The numeric index signature reflects a “reverse mapping” that is automatically generated in every enum object, as described in section 9.4. The reverse mapping provides a convenient way to obtain the string representation of an enum value. For example

var c = Color.Red;
console.log(Color[c]);  // Outputs "Red"

9.2    Enum Members

The body of an enum declaration defines zero or more enum members which are the named values of the enum type. Each enum member has an associated numeric value of the primitive type introduced by the enum declaration.

EnumBody:
ConstantEnumMemberList   
,opt
ConstantEnumMemberList   
,   ComputedEnumMemberList   ,opt
ComputedEnumMemberList   
,opt

ConstantEnumMemberList:
ConstantEnumMember
ConstantEnumMemberList   
,   ConstantEnumMember

ConstantEnumMember:
PropertyName
PropertyName   =   IntegerLiteral

IntegerLiteral:
SignedInteger
HexIntegerLiteral

ComputedEnumMemberList:
ComputedEnumMember
ComputedEnumMemberList   
,   ComputedEnumMember

ComputedEnumMember:
PropertyName   
=   AssignmentExpression

Enum members are either constant members or computed members. Constant members have known constant values that may be substituted in place of references to the members at compile-time. Computed members have values that are computed at run-time and not known at compile-time.

TODO: Decide whether references to constant members are always replaced with their values or whether this is a compiler option.

The body of an enum declaration consists of a list of zero or more constant members followed by zero or more computed members.

A constant member declared with an integer literal value is assigned that value. A constant member declared without an integer literal value is assigned the value of the preceding constant member plus one, or the value zero if it is the first member in the enum body. The values of constant members are computed at compile-time and may be substituted for references to the members in the generated JavaScript code.

Expressions specified for computed members must produce values of type Any, the Number primitive type, or an enum type. The values of computed members are not known at compile-time and no substitution is performed for references to computed members.

In the example

enum Test {
    A,
    B,
    C = 10,
    D,
    E = Math.floor(Math.random() * 1000)
}

‘A’, ‘B’, ‘C’, and ‘D’ are constant members with values 0, 1, 10, and 11 respectively, and ‘E’ is a computed member.

In the example

enum Style {
    None = 0,
    Bold = 1,
    Italic = 2,
    Underline = 4,
    Emphasis = Style.Bold | Style.Italic,
    Hyperlink = Style.Bold | Style.Underline
}

the first four members are constant members and the last two are computed members. Note that computed member declarations can reference previously declared members. Also, because enums are subtypes of the Number primitive type, numeric operators, such as the bitwise OR operator, can be used to compute enum values.

9.3    Declaration Merging

Enums are “open-ended” and enum declarations with the same qualified name relative to a common root (as defined in section 2.3) define a single enum type and contribute to a single enum object.

It isn’t possible for one enum declaration to continue the automatic numbering sequence of another, and when an enum type has multiple declarations, only one declaration is permitted to omit a value for the first member.

9.4    Code Generation

An enum declaration generates JavaScript equivalent to the following:

var <EnumName>;
(function (
<EnumName>) {
    
<EnumMemberAssignments>
})(
<EnumName>||(<EnumName>={}));

EnumName is the name of the enum.

EnumMemberAssignments is a sequence of assignments, one for each enum member, in order they are declared, of the form

<EnumName>[<EnumName>.<MemberName> = <MemberValue>] = "<MemberName>";

where MemberName is the name of the enum member and MemberValue is the assigned constant value or the code generated for the computed value expression.

TODO: In general, when generating code for a property access, use quoted names and bracket notation for non-identifier member names.

For example, the ‘Color’ enum example from section 9.1 generates the following JavaScript:

var Color;
(function (Color) {
    Color[Color.Red = 0] = "Red";
    Color[Color.Green = 1] = "Green";
    Color[Color.Blue = 2] = "Blue";
})(Color||(Color={}));

 


TypeScript Language Specification (converted to HTML pages by @Bartvds)

Version 0.9.1

August 2013

Microsoft is making this Specification available under the Open Web Foundation Final Specification Agreement  Version 1.0 ('OWF 1.0') as of October 1, 2012. The OWF 1.0 is available at  http://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0.

TypeScript is a trademark of Microsoft Corporation.