TS1484: 'X' is a type and must be imported using a type-only import when verbatimModuleSyntax is enabled
With `verbatimModuleSyntax` enabled, TypeScript no longer decides for you whether an import is type-only or a real runtime import — it emits imports exactly as written. If you import something that's only ever used as a type, you must write `import type { X }` explicitly, since a regular `import { X }` would try to import a non-existent runtime value.
What causes this error
verbatimModuleSyntax makes TypeScript emit imports/exports exactly as written, with no implicit elision of type-only imports at compile time. Previously, TypeScript could silently detect that an imported name was only used as a type and drop the import from the compiled output. With this option on, that inference is gone — you have to be explicit, and a plain `import { SomeInterface }` for a type-only name is now an error rather than a silent optimization.
The Fix
// Wrong — SomeInterface is only ever used as a type, but imported as a value
import { SomeInterface } from './types'; // TS1484
function process(data: SomeInterface) { /* ... */ }
// Fix — mark it explicitly as a type-only import
import type { SomeInterface } from './types';
function process(data: SomeInterface) { /* ... */ }
// If a module has a mix of value and type exports, use inline type modifiers
import { runtimeFn, type SomeInterface } from './mixed-module';Common causes / variations
- Importing an interface/type alongside runtime values from the same module without the `type` modifier
- Enabling `verbatimModuleSyntax` on an existing codebase that relied on TypeScript's automatic type-only import elision
- A barrel file re-exporting both types and values, requiring careful `export type` annotations to stay consistent
Related errors
See also: ERR_REQUIRE_ESM, Cannot find module (missing extension in ESM).
Comments
Loading comments...