Skip to content

useImportType (since v1.5.0)

Diagnostic Category: lint/style/useImportType

Sources:

Promotes the use of import type for types.

TypeScript allows specifying a type qualifier on an import to indicate that the import doesn’t exist at runtime. This allows transpilers to safely drop imports of types without looking for their definition. This also ensures that some modules are not loaded at runtime.

The rule ensures that all imports used only as a type use a type-only import. It also groups inline type imports into a grouped import type.

Caveat with TypeScript experimental decorators

Section titled Caveat with TypeScript experimental decorators

Some frameworks like Angular and NestJS rely on experimental TypeScript decorators which allow code to be generated based on type annotations. This is mainly used for dependency injection.

Since Biome doesn’t know how a decorator is implemented, it is unable to detect that an import used as a type is also used as a value in the code generated by a decorator. This leads Biome to suggest importing some imports as type, which are actually used as value at runtime.

We haven’t found a way to support this pattern yet. We recommend disabling this rule when using such decorators.

This rule respects the jsxRuntime setting and will make an exception for React globals if it is set to "reactClassic".

import { A } from "./mod.js";
type TypeOfA = typeof A;
let a: A;
style/useImportType.js:1:1 lint/style/useImportType  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   All these imports are only used as types.
  
  > 1 │ import { A } from "./mod.js";
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    2 │ type TypeOfA = typeof A;
    3 │ let a: A;
  
   Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
  
   Safe fix: Use import type.
  
    1 │ import·type·{·A·}·from·"./mod.js";
         +++++                      
import { type A, type B } from "./mod.js";
style/useImportType.js:1:1 lint/style/useImportType  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   All these imports are only used as types.
  
  > 1 │ import { type A, type B } from "./mod.js";
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    2 │ 
  
   Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
  
   Safe fix: Use import type.
  
    1  - import·{·type·A,·type·B·}·from·"./mod.js";
      1+ import·type·{·A,·B·}·from·"./mod.js";
    2 2  
  
import { type A, B } from "./mod.js";
let c: A;
let d: typeof B;
style/useImportType.js:1:1 lint/style/useImportType  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   All these imports are only used as types.
  
  > 1 │ import { type A, B } from "./mod.js";
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    2 │ let c: A;
    3 │ let d: typeof B;
  
   Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
  
   Safe fix: Use import type.
  
    1  - import·{·type·A,·B·}·from·"./mod.js";
      1+ import·type·{·A,·B·}·from·"./mod.js";
    2 2  let c: A;
    3 3  let d: typeof B;
  
import type { A } from "./mod.js";
let a: A;
import { B } from "./mod.js";
let a: B = new B();
import { type A, B } from "./mod.js";
let c: A;
let d = new B();

The rule ignores unused imports and imports with import attributes.

import { A } from "./mod.js";
import { B } from "./mod.js" with {};
export type { B };