TypeScript: Imported const enum is not inlined in generated code

TypeScript Version: 2.4.0

Code

// a.ts
export const enum Foo {
  Bar = 'bar'
}

// b.ts
import { Foo } from './a'

Foo.Bar // TypeError or ReferenceError, depending on how it's compiled

Expected behavior: Foo.Bar to be replaced with 'bar'

Actual behavior: The import is deleted and Foo.Bar is left as is

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 36
  • Comments: 25 (10 by maintainers)

Most upvoted comments

I’ve also encountered this problem when transpileOnly: true. Without transpileOnly, I can’t use multi-threading to speed up my webpack build (ts-loader, happypack, fork-ts-checker-webpack-plugin). Unfortunately, I’m dealing with +100,000 lines of legacy code, so removing all const enums is not feasible.

transpileOnly means transpile every file one at a time… when the compiler is looking at one file, it has no way to know if the reference it is looking at is a const enum or not, since the declaration is in another file that it does not have access to…

so I do not think you can mix these two concepts, const enums (require whole program information), and transpileOnly (one file at a time).

I’ve also encountered this problem when transpileOnly: true. Without transpileOnly, I can’t use multi-threading to speed up my webpack build (ts-loader, happypack, fork-ts-checker-webpack-plugin). Unfortunately, I’m dealing with +100,000 lines of legacy code, so removing all const enums is not feasible.

Typescript version: 2.6.1

in my d.ts file I declare a const enum and use it in an interface in that same file.

declare const enum LMListType {
  DEFAULT = 'default',
  SELECT = 'select',
  HELPER = 'helper',
}

interface LMListSpec {
  ...
  listType: LMListType,
  ...
}

I use it like this in my component code (angular4): myComponent.ts:

if (this.listSpec.listType === LMListType.DEFAULT) {   
   etc...
}

Everything compiles but I get runtime errors since there is no LMListType. In-lining would fix this for me I think.

I could move my d.ts file to a regular ts file but then I have to import all of it’s interfaces in each component that uses them. I’d like to avoid that.

What is suggested for this issue?

@funder7 No, it hasn’t been resolved.

I encountered this bug with TypeScript 4.0.2. For me, it caused ReferenceError at runtime, until I disabled isolatedModules in my tsconfig.json.

p7.zip

Version 3.8.0-dev.20200130

index.js

"use strict";

//import { Enum01 } from './temp';
//
//export const aa = {
//	a01: Enum01.A,
//}
exports.__esModule = true;
exports.bb = {
    a02: temp_1.Enum02.A
};

Enum02.A didn’t emit as 0 or import temp.ts


{
  "compilerOptions": {
    "target": "ESNext",
    "module": "CommonJS",
    "isolatedModules": true
  }
}

temp.ts

//export enum Enum01 {
//	A
//}

export const enum Enum02 {
	A
}

index.ts

//import { Enum01 } from './temp';
//
//export const aa = {
//	a01: Enum01.A,
//}

import { Enum02 } from './temp';

export const bb = {
	a02: Enum02.A
}

If that’s the case, then perhaps it should be an error to export them to begin with (at least in non-.d.ts cases). It’s not possible to make any meaningful cross-module use of them as it is.