Skip to content

const/non-const enum cleanup #2183

Closed
Closed
@RyanCavanaugh

Description

@RyanCavanaugh
Member

Key points from discussion from this morning:

  1. Assume all non-ambient members of non-const enums are computed (even those initialized with literals), both for inlining purposes and for .d.ts generation purposes
  2. Continue to aggressively compute initializer expressions in both const and non-const enums
  3. Ambient non-const enums preserve existing behavior (computed iff there is no initializer)
  4. Continue to have --preserveConstEnums flag, which causes emit of the lookup object for const enums but does not change inlining

Tag @ahejlsberg

Activity

danquirk

danquirk commented on Mar 2, 2015

@danquirk
Member

Note this would likely be a breaking change

RyanCavanaugh

RyanCavanaugh commented on Mar 2, 2015

@RyanCavanaugh
MemberAuthor

A retelling of how we got here (note: using "1.0" here as a stand-in for all behavior prior to Vlad's proposed PR which does more aggressive initializer folding)

For regular enums, in 1.0, we would only inline constant members, and a member was only constant if its initializer was a literal. This led to a "workaround" (or "design feature", depending) that you could use an equivalent syntactic form to get a computed enum member, e.g. enum X { Y = (3) }. This is an important scenario for when you don't want to ship a .d.ts file that hardcodes in enum values because you intend to change those enum values in the future.

Vlad's change more aggressively resolves computational expressions in enum member initializers, so the member Y = (3) or Y = 3+0 now looks like a constant initializer rather than a computed one. This is an important breaking change for the aforementioned people who want to have a "constancy not guaranteed" .d.ts file, or who are doing wacky separate compilation (e.g. Monaco) and don't want referring implementation files to have their enum references inlined.

One proposed workaround was that you would initialize your "should not be inlined" enum members via a function call (e.g. enum X = Math.min(3)), but this is obviously weird.

The cleanest place to land is that we treat all non-const enum members as computed. This is a breaking change, but only in one scenario -- where a non-ambient enum is declared with constant members, consumed only at inlined sites, and the emitted JS (of the lookup object) is excluded from the script context. This scenario is easily fixed, though, because any enum fitting this profile can have the const keyword added to its declaration to force inlining at all consumption sites (which obviously must work, if all the non-const enum consumption sites were originally inlined).

added
FixedA PR has been merged for this issue
CommittedThe team has roadmapped this issue
and removed on Mar 19, 2015
added this to the TypeScript 1.5 milestone on Mar 19, 2015
RyanCavanaugh

RyanCavanaugh commented on Apr 3, 2015

@RyanCavanaugh
MemberAuthor

Ref #2594

locked and limited conversation to collaborators on Jun 18, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    CommittedThe team has roadmapped this issueFixedA PR has been merged for this issueSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @RyanCavanaugh@danquirk@mhegazy

        Issue actions

          const/non-const enum cleanup · Issue #2183 · microsoft/TypeScript