Description
openedon Nov 2, 2014
Currently accessing enum members is inlined only if enum member initializer is numeric constant value, computed members are never inlined (note that this aspect is not covered by the spec so alternative TypeScript implementations or future version of the compile might have different behavior). This means that in runtime accessing computed member will always be emitted as property access which might be a blocker for optimizations in JavaScript engines (#917).
Proposal:
Introduce a new kind of enum - 'const enum' with more aggressive constant folding in initializers. Basically enum member initializer in const enum members should always be a constant expression that can be evaluated in compile time. Set of operations permitted in initializer should include arithmetic and bitwise operations. Enum member initializer can refer to const enum members that were declared prior to current member.
Having numeric values for all enum members on hands will allow compiler to always embed values instead of emitting property\index access.
const enums should leave nothing in generated code, we won't emit its declaration\reverse mapping for named. Because of this requirement const enums will have following restrictions:
- const enums are still open ended but they can be merged only with other const enums
- const enums cannot be merged with instantiated modules
- const enum object type is permitted to be used only in:
- as 'object' property access expressions
- as 'object' in indexed access expression when 'index' is a string literal
- on the right hand side of
=
in import declarations - in export assignment
Rationale: it should be illegal to somehow capture instance of const enum object since const enum is completely erased at compile time.
const enum E { V }
module E { var x = 1 } // assuming this is legal
var e = E;
var v = e.V // will be undefined in runtime
modules containing only const enums will be considered uninstantiated from the emit perspective so importing such module not be reflected in generated code. NOTE: The only exception from this rule is when const enum is exported from the external module - in this case we'll still generate import for this module.
PR with suggested implementation: #970.