Description
Bug Report
I've encountered a pattern where transpileModule
emits unsafe code at runtime, and isolatedModules
does not report errors to help catch this case.
Consider the following:
import IInterface = My.Application.Interfaces.IInterface;
export type { IInterface };
Under a "normal" full compile, TypeScript will recognize that IInterface
only used as a type, and will essentially emit nothing for either of these lines.
export {};
But when this same snippet is ran through transpileModule
, the "import equals" declaration is preserved as a variable.
var IInterface = My.Application.Interfaces.IInterface;
export {};
It isn't safe to assume that My.Application.Interfaces
is going to be available at runtime, and this difference could lead to runtime errors.
🔎 Search Terms
isolatedModules import equals namespace type only
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about
transpileModule
.
⏯ Playground Link
Playground link demonstrating the desired output:
https://www.typescriptlang.org/play?isolatedModules=true&ssl=4&ssc=28&pln=3&pc=1#code/PTAEAEEsGcHsBsCGAXApgEwLK3QV3qtAFyjIBOuqAUFZALYAOsZyoAkmwHZpkBmiAY1SgAvKEwBPAHQBBBg3iQBKSLE5SuPfkOgbNqPoNQBuKqgAeTFqQkNhAb3b7DQ0AF9TVEKAAiqAUhkGKBwdKgA7gAWBsKo8NCoRFTo-oHCAObwsABGiPCg9lSgxaCciGHQDEbi0nIKSipqGtwG2oQFRSVdkC0uwhy9bQVuncUjbkA
Code Sandbox showing the problematic transpileModule
behavior:
https://codesandbox.io/s/cocky-mcclintock-9iuqd9?file=/src/index.js
💻 Code
This is essentially what the Code Sandbox is doing:
const result = ts.transpileModule(`
import IInterface = My.Application.Interfaces.IInterface;
export type { IInterface };
`,
{
compilerOptions: {
module: ts.ModuleKind.ESNext
}
}
);
🙁 Actual behavior
var IInterface = My.Application.Interfaces.IInterface;
export {};
🙂 Expected behavior
export {};
Suggested Fix
- Correctly elide the import equals declaration, just like regular import statements.
- Or protect developers against this runtime risk through an error when
isolatedModules
is enabled. (However, I don't know of a great replacement for this syntax if this was the direction taken.)
For reference, #45579 was recently fixed, where isolatedModules
now reports an error for code like this:
export import JSX = JSXInternal;
It seems to me like developers are going to quickly fix these cases by doing something like this:
import JSX = JSXInternal;
export type { JSX };
And that is the exact pattern I am reporting in this issue.