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
@Kovensky, I cannot seem to reproduce this behavior in typescript@next or in our 2.4 release branch. This may have been fixed by another change. Can you verify against typescript@next? If you are still seeing this, we may need more information.
It still happens with 2.5.0-dev.20170622.
It looks like --isolatedModules is causing the import { Foo } to be elided as a type import (correct), but is not replacing the Foo.Bar value in the processed source text. Disabling --isolatedModules generates correct code.
Unfortunately const enums are type-directed, but emit in isolatedModules is type-agnostic (it has to be, otherwise the modules couldn't be compiled in isolation).
If that鈥檚 the case, then perhaps it should be an error to export them to begin with (at least in non-.d.ts cases). It鈥檚 not possible to make any meaningful cross-module use of them as it is.
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?
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
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).
Which is why I now think that exporting a const enum should be a compile error.
yes. it should be an error under --isolatedModules. and this bug tracks adding that.
@mhegazy What about under --transpileOnly?
Not sure what you mean, but asserting that the code is safe to transpile one file at a time is what --isloatedModules do.
I meant, should there also be a compile-time error when using --transpileOnly and exporting const enums.
what is --transpileOnly? that is not a compiler option.
Sorry, I got confused. I meant the transpile: true option of ts-loader, as you mentioned here. But that's an issue to be taken up with ts-loader.
When --isolatedModules is specified, could const enums instead be output as regular (non-const) enums?
Either that, or they should not be allowed to be exported to begin with.
Having this issue now with the vue cli. I don't know why but it was working before.. The correct settings are to turn the ts-loader transpileOnly: false and isoLatedModules: false and it should work ? Scratching my head because it was working fine until I set transpileOnly to true, which I flipped back to false but now none of it works...
//vue cli plugin typescript webpack config
addLoader({
loader: "ts-loader",
options: {
transpileOnly: false,
appendTsSuffixTo: ["\\.vue$"],
// https://github.com/TypeStrong/ts-loader#happypackmode-boolean-defaultfalse
happyPackMode: useThreads
}
});
//exporting a const enum that aren't being inlined
export const Directions {
UP
}
Alright, seems like mode has to be set to production. Guess I'll try to look into what happens in development later.
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
}
Hi, what's the status of this issue? Can it be considered resolved in v3.x ?
@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.
Most helpful comment
I've also encountered this problem when
transpileOnly: true. WithouttranspileOnly, 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