oxc-project/oxc · warning · OxcDiagnostic

Imports {type_imports} are only used as type.

Error message

Imports {type_imports} are only used as type.

What it means

Mixed-usage variant of typescript/consistent-type-imports: within one import declaration only some specifiers are used exclusively as types, and their names are interpolated into the message. The expected remedy is the inline `type` modifier on just those specifiers (or splitting the declaration), since converting the whole import would drop the value bindings.

Source

Thrown at crates/oxc_linter/src/rules/typescript/consistent_type_imports.rs:45

    OxcDiagnostic::warn("`import()` type annotations are forbidden.")
        .with_help("Replace `import()` type annotations with a regular type import. For example, change `type T = import('module').Type` to `import type { Type } from 'module'; type T = Type`.")
        .with_label(span)
}

fn avoid_import_type_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Use an `import` instead of an `import type`.")
        .with_help("Replace the `import type` declaration with a regular `import` declaration. For example, `import type { Type } from 'module'` would become `import { Type } from 'module'`.")
        .with_label(span)
}
fn type_over_value_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("All imports in the declaration are only used as types. Use `import type`.")
        .with_help("Replace the `import` declaration with `import type`. For example, change `import { Type } from 'module'` would become `import type { Type } from 'module'`.")
        .with_note("Using `import type` for type-only imports helps with tree-shaking, makes it clear that these imports don't affect runtime code, and can improve build performance by allowing bundlers to eliminate unused type imports.")
        .with_label(span)
}

fn some_imports_are_only_types_diagnostic(span: Span, type_imports: &str) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("Imports {type_imports} are only used as type.")).with_label(span)
}

#[derive(Debug, Default, Clone, Deserialize)]
pub struct ConsistentTypeImports(Box<ConsistentTypeImportsConfig>);

impl Deref for ConsistentTypeImports {
    type Target = ConsistentTypeImportsConfig;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

// <https://github.com/typescript-eslint/typescript-eslint/blob/v8.9.0/packages/eslint-plugin/docs/rules/consistent-type-imports.mdx>
#[derive(Debug, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct ConsistentTypeImportsConfig {
    /// Disallow using `import()` in type annotations, like `type T = import('foo')`

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Mark only the type-only specifiers inline: `import { type Foo, bar } from './mod';`
  2. Or split the declaration: `import { bar } from './mod'; import type { Foo } from './mod';`
  3. Apply mechanically with `oxlint --fix` after setting "fixStyle": "inline-type-imports"

Example fix

// before
import { Foo, bar } from './mod';
let x: Foo = bar();

// after
import { type Foo, bar } from './mod';
let x: Foo = bar();
Defensive patterns

Strategy: validation

Validate before calling

// Codify the inline style so autofix matches team preference:
// .oxlintrc.json
{
  "rules": {
    "typescript/consistent-type-imports": [
      "warn", { "prefer": "type-imports", "fixStyle": "inline-type-imports" }
    ]
  }
}

Prevention

When it happens

Trigger: `import { Foo, bar } from './mod';` where Foo appears only in type positions while bar is called or otherwise used as a value. The rule reports the declaration listing Foo in the message.

Common situations: Barrel-file style imports mixing types and utilities; refactors that remove the last value usage of one specifier but not others; teams standardizing on inline-type-imports fixStyle during migration.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/f5967edf8b64e550. Report an issue: GitHub.