I imported a type. Why did code run?
With verbatimModuleSyntax enabled, an inline type-only name can disappear while an empty JavaScript import remains. That import still evaluates the dependency.
Use a whole import type to remove this runtime dependency. Use a separate side-effect import when startup code is intended. Other imports can still load the module; this reproduction runs compiler output without a bundler.
Understand it. Then fix it.
The type goes. The import stays.
With the verbatim module syntax setting on, that form removes the type name. It leaves an empty import in the JavaScript. An empty import still loads the module.
// TypeScript
import { type Model }
from "./dep.js";
// Emitted JavaScript
import {} from "./dep.js";Nothing imported. Something executed.
Empty means no names are imported. It does not mean skip the file. JavaScript still runs that file’s top-level code. Here, it prints loaded.
// dep.ts
export interface Model {
id: string;
}
console.log("loaded");Move type outside the braces.
Put type before the braces. Now TypeScript removes the whole import. In our isolated test, loaded no longer prints. Same dependency · fresh process for each test.
import type { Model }
from "./dep.js";
// No dep.js import in the outputNeed startup code? Say so directly.
If you need its startup code, add a separate import. Other imports can still load the file. This test runs compiler output directly; a bundler adds another step. No claim about every bundler or configuration.
import type { Model }
from "./dep.js";
import "./dep.js";Code blocks are teaching excerpts. Keep the surrounding error handling and application requirements.
Save the code excerpts ↓Read the full transcript
I imported one TypeScript type. Why did the other file still run? With the verbatim module syntax setting on, that form removes the type name. It leaves an empty import in the JavaScript. Empty means no names are imported. It does not mean skip the file. JavaScript still runs that file’s top-level code. Here, it prints loaded. So how do I keep the type without loading that file? Put type before the braces. Now TypeScript removes the whole import. In our isolated test, loaded no longer prints. If you need its startup code, add a separate import. Other imports can still load the file. This test runs compiler output directly; a bundler adds another step. I asked for a name tag. The whole employee showed up.