angular-cli: const enum is broken

OS?

Mac OSX Sierra

Versions.

1.0.0-beta.17

Repro steps.

ng new --prefix=t check-enum cd check-enum/ ng serve

then add to main.ts (no matter, may be any *.ts)

declare namespace Sts {
  export const enum A{
    a, b, c
  }
}
console.log(Sts.A.a, Sts.A.b);

The log given by the failure.

main.bundle.js:65131 Uncaught ReferenceError: Sts is not defined

Actual in main.bundle.js

console.log(Sts.A.a, Sts.A.b); (see at Source panel of Chrome Developer Tools)

Expected in main.bundle.js

console.log(0 /* a */, 1 /* b */);

If I run tsc from src directory, this code will be in dist/out-tsc, as expected. TypeScript is OK!

Mention any other details that might be useful.

I donn’t know, where is a mistake, in angular-cli or its configuration or deps. Generated code is same, as without const keyword. This is very strange.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 13
  • Comments: 21 (2 by maintainers)

Most upvoted comments

@sumitarora The problem isn’t that we can’t compare const enums, it’s that the values we’re comparing against aren’t transpiled (and thus result in runtime errors). If we take your example (a little shortened):

// Ambient declaration in another .d.ts file
namespace Validation {
  export const enum A {
    a, b, c
  }
}

// Usage code
const x: Validation.A = Validation.A.c;
switch (x.valueOf()) {
  case Validation.A.a:
    console.log('a');
    break;
}

Should transpile to:

var x = 2;
switch (x.valueOf()) {
    case 0:
        console.log('a');
        break;
}

But instead transpiles to:

var x = Validation.A.c;
switch (x.valueOf()) {
    case Validation.A.a:
        console.log('a');
        break;
}

And naturally it cannot find Validation.A.c and Validation.A.a at runtime.

We want to use CLI in out current project for better updateability, but could not switch due to the enum problem. We also use Typlite to generate our enums.

Is there anybody investigating this problem and can say when the problem will be solved?

I’ve many enums in my project and that I can’t use them is a really show stopper for me to use the cli.

Currently I am using pure webpack 2 and there everything is workingfine with the Enums here my TS loader is the following rule

test: /\.ts$/,
       use: [
         '@angularclass/hmr-loader?pretty=' + !isProd + '&prod=' + isProd, 
         'awesome-typescript-loader',
         'angular2-template-loader'
     ],

I have a .NET MVC Project and I am using TypeLite to generate TypeScript Enums out of my C# Enums. Here a Enums.ts file is created with many Enums inside like

module  Internal.Notification.DomainModel {
  export const enum NotificationType {
	Information = 0,
	Success = 1,
	Warning = 2,
	Error = 3
   }
}
module  Internal.Repository.DomainModel {
  export const enum SortDirectionEnum {
	Ascending = 0,
	Descending = 1
   }
}

I am currently trying to migrate from my own webpack 2 build to the cli but currently it seems not possible.

@imiuka your Solution with “preserveConstEnums” is not working here and the third solution is too complex, there I can stay with my current own WebPack Build Setup.

@Gustorn why is the third Solution from @imiuka not implemented in the CLI with an addional Parameter or so and perhaps can someone explain me why my TypeScript Loader setup makes no Problems with the Enums?

A working solution for such a common problem would be really nice.

We also ran into this while upgrading to a Webpack-based/AOT-enabled build system. We have some tooling set up that automatically generates d.ts files for all of our web-facing model classes. This maps native enums - very correctly - to const enums.

The automatically generated .d.ts file:

declare module server {
    const enum Status {
        OK
    }
}

The problem arose when we tried to use these enum values directly:

export function processStatus(status: server.Status) {
    switch (status) {
        server.Status.OK:
            // Custom code here
            break;
    }
}

Luckily code like this was few and far-between so I solved the issue by replacing the generated enums with their constant values. This solution is of course very far from ideal: we lose type safety and the code becomes harder to read. Non-ambient const enums are properly transpiled.

Since this issue is 6 months old and is a pretty severe codegen bug some official word would be really appreciated.

This is blocking me as well. version 1.0.0-beta.25.5

With CLI 1.5+ and Angular 5, the use of transpileModule has been eliminated. Note that Angular 4 uses the previous compiler pipeline so if const enum support is required please update to Angular 5+.

The thing is, ts-loader with its fork-checker-plugin beats awesome-typescript-loader in some of our projects and it actually generates correct code.

This is still a blocking issue for me. Repro steps:

  • create a new project (ng new)
  • add a new ts file (enums.ts for example)
  • make the contents of this file module enums { export const enum myEnum { value0 = 0 } }
  • add this file to the tsconfig.app (using “files” or “include” for example)
  • reference your enum in app.component.ts let x = enums.myEnum.value0;
  • ng serve (or test or e2e)

Expected: The app builds and runs without error Actual: The app builds without error. However, the module containing your enum will not be defined at runtime. Error message: Uncaught ReferenceError: enums is not defined.

The module not being defined at runtime is actually expected. The compiler should have replaced the enum reference with the value because this enum is defined as a constant. This is unexpected and undesirable behavior.

This issue prevents me from using angular-cli in projects where I have split out enumerations into their own files for reuse. What is worse is that I can not use tools like typelite to automatically translate my enumerations from .Net to typescript.

@angular/cli: 1.0.4 node: 6.10.2 os: win32 x64 @angular/common: 4.1.3 @angular/compiler: 4.1.3 @angular/core: 4.1.3 @angular/forms: 4.1.3 @angular/http: 4.1.3 @angular/platform-browser: 4.1.3 @angular/platform-browser-dynamic: 4.1.3 @angular/router: 4.1.3 @angular/cli: 1.0.4 @angular/compiler-cli: 4.1.3