Repository: biomejs/biome (language: rust)

Issue:
💅 `useImportType` fails to remove inline `type` imports when the group also uses a `type` import
### Environment information

```bash
CLI:
  Version:                      1.9.3
  Color support:                true

Platform:
  CPU Architecture:             x86_64
  OS:                           linux

Environment:
  BIOME_LOG_PATH:               unset
  BIOME_LOG_PREFIX_NAME:        unset
  BIOME_CONFIG_PATH:            unset
  NO_COLOR:                     unset
  TERM:                         "xterm-256color"
  JS_RUNTIME_VERSION:           "v20.17.0"
  JS_RUNTIME_NAME:              "node"
  NODE_PACKAGE_MANAGER:         "pnpm/9.11.0"

Biome Configuration:
  Status:                       Loaded successfully
  Formatter disabled:           false
  Linter disabled:              false
  Organize imports disabled:    false
  VCS disabled:                 false

Linter:
  JavaScript enabled:           true
  JSON enabled:                 true
  CSS enabled:                  true
  GraphQL enabled:              false
  Recommended:                  true
  All:                          false
  Enabled rules:
  performance/noDelete
  suspicious/noCatchAssign
  suspicious/noUnsafeNegation
  complexity/useLiteralKeys
  suspicious/noClassAssign
  style/useImportType
  complexity/noMultipleSpacesInRegularExpressionLiterals
  a11y/useValidLang
  complexity/noUselessEmptyExport
  suspicious/useNamespaceKeyword
  suspicious/useValidTypeof
  a11y/useValidAriaRole
  correctness/noConstantCondition
  a11y/useAriaActivedescendantWithTabindex
  suspicious/noAssignInExpressions
  style/useDefaultParameterLast
  complexity/noEmptyTypeParameters
  correctness/noConstructorReturn
  style/useSelfClosingElements
  suspicious/noDuplicateParameters
  suspicious/noDuplicateSelectorsKeyframeBlock
  correctness/noUnknownProperty
  style/useTemplate
  correctness/noUnusedLabels
  complexity/noUselessTernary
  correctness/noUnreachableSuper
  suspicious/noCompareNegZero
  suspicious/noExplicitAny
  correctness/noSwitchDeclarations
  a11y/noAutofocus
  correctness/noUnsafeOptionalChaining
  correctness/noConstAssign
  suspicious/noControlCharactersInRegex
  complexity/noUselessTypeConstraint
  style/noVar
  suspicious/noDoubleEquals
  suspicious/noRedundantUseStrict
  style/useLiteralEnumMembers
  suspicious/noGlobalIsNan
  suspicious/noEmptyInterface
  suspicious/noConstEnum
  suspicious/noMisleadingCharacterClass
  correctness/noPrecisionLoss
  a11y/noLabelWithoutControl
  suspicious/noRedeclare
  correctness/noStringCaseMismatch
  correctness/noSetterReturn
  correctness/noInvalidConstructorSuper
  suspicious/noImplicitAnyLet
  suspicious/noFallthroughSwitchClause
  suspicious/noUnsafeDeclarationMerging
  complexity/noUselessThisAlias
  correctness/noUnreachable
  a11y/useKeyWithClickEvents
  suspicious/noDuplicateObjectKeys
  complexity/noThisInStatic
  complexity/useOptionalChain
  correctness/noInnerDeclarations
  style/noParameterAssign
  suspicious/noDuplicateCase
  a11y/useValidAnchor
  complexity/useRegexLiterals
  correctness/noSelfAssign
  correctness/noInvalidBuiltinInstantiation
  style/noUselessElse
  style/useShorthandFunctionType
  suspicious/noShadowRestrictedNames
  correctness/noInvalidDirectionInLinearGradient
  suspicious/noImportantInKeyframe
  a11y/useMediaCaption
  complexity/noUselessLabel
  complexity/noUselessCatch
  correctness/noUnsafeFinally
  a11y/useAriaPropsForRole
  correctness/noNonoctalDecimalEscape
  style/useEnumInitializers
  a11y/useHtmlLang
  suspicious/noDuplicateTestHooks
  complexity/noStaticOnlyClass
  style/useWhile
  complexity/useArrowFunction
  style/noInferrableTypes
  a11y/noNoninteractiveTabindex
  complexity/useSimpleNumberKeys
  correctness/useYield
  a11y/noInteractiveElementToNoninteractiveRole
  style/useNumericLiterals
  correctness/noUnnecessaryContinue
  suspicious/noApproximativeNumericConstant
  suspicious/noImportAssign
  suspicious/noLabelVar
  correctness/noGlobalObjectCalls
  suspicious/useDefaultSwitchClauseLast
  correctness/noUnknownUnit
  a11y/useAltText
  correctness/noEmptyCharacterClassInRegex
  suspicious/noSparseArray
  a11y/useIframeTitle
  complexity/noBannedTypes
  a11y/noSvgWithoutTitle
  correctness/noVoidElementsWithChildren
  style/useAsConstAssertion
  correctness/useJsxKeyInIterable
  style/useExportType
  complexity/noUselessLoneBlockStatements
  suspicious/noDebugger
  a11y/useValidAriaValues
  style/noArguments
  suspicious/noCommentText
  a11y/useFocusableInteractive
  correctness/noUnmatchableAnbSelector
  suspicious/noGlobalAssign
  suspicious/noDuplicateJsxProps
  suspicious/noMisleadingInstantiator
  a11y/noPositiveTabindex
  correctness/noEmptyPattern
  complexity/noExcessiveNestedTestSuites
  security/noDangerouslySetInnerHtmlWithChildren
  a11y/useKeyWithMouseEvents
  suspicious/noExtraNonNullAssertion
  suspicious/noPrototypeBuiltins
  correctness/noRenderReturnValue
  correctness/useExhaustiveDependencies
  security/noGlobalEval
  style/noNonNullAssertion
  a11y/noRedundantRoles
  complexity/useFlatMap
  correctness/useIsNan
  style/useConst
  suspicious/noGlobalIsFinite
  suspicious/noSelfCompare
  suspicious/noShorthandPropertyOverrides
  suspicious/noAsyncPromiseExecutor
  suspicious/noDuplicateFontNames
  suspicious/noThenProperty
  suspicious/useGetterReturn
  security/noDangerouslySetInnerHtml
  style/useNodejsImportProtocol
  a11y/noDistractingElements
  suspicious/noArrayIndexKey
  complexity/noWith
  suspicious/noDuplicateClassMembers
  complexity/noExtraBooleanCast
  performance/noAccumulatingSpread
  a11y/useValidAriaProps
  a11y/noRedundantAlt
  correctness/noChildrenProp
  correctness/noUnknownFunction
  correctness/noInvalidPositionAtImportRule
  suspicious/noConfusingLabels
  suspicious/noSuspiciousSemicolonInJsx
  suspicious/noConfusingVoidType
  suspicious/noFocusedTests
  a11y/useButtonType
  a11y/useSemanticElements
  a11y/noAriaUnsupportedElements
  correctness/noInvalidGridAreas
  correctness/noFlatMapIdentity
  a11y/noBlankTarget
  a11y/useHeadingContent
  correctness/useValidForDirection
  correctness/noVoidTypeReturn
  correctness/noInvalidUseBeforeDeclaration
  a11y/noAriaHiddenOnFocusable
  a11y/useGenericFontNames
  correctness/noUnknownMediaFeatureName
  a11y/useAnchorContent
  complexity/noUselessRename
  style/useNumberNamespace
  complexity/noUselessConstructor
  a11y/noAccessKey
  style/useExponentiationOperator
  style/noUnusedTemplateLiteral
  complexity/noUselessSwitchCase
  style/useSingleVarDeclarator
  suspicious/noExportsInTest
  a11y/noNoninteractiveElementToInteractiveRole
  style/noCommaOperator
  suspicious/noDuplicateAtImportRules
  suspicious/useIsArray
  a11y/noHeaderScope
  complexity/noUselessFragments
  suspicious/noMisrefactoredShorthandAssign
  suspicious/noEmptyBlock
  complexity/noForEach
  correctness/noUnusedImports
  suspicious/noFunctionAssign

Workspace:
  Open Documents:               0
```


### Rule name

useImportType

### Playground link

https://biomejs.dev/playground/?code=aQBtAHAAbwByAHQAIAB0AHkAcABlACAAewAgAHQAeQBwAGUAIABGAG8AbwAsACAAdAB5AHAAZQAgAEIAYQByACAAfQAgAGYAcgBvAG0AIAAiAHMAbwBtAGUAdwBoAGUAcgBlACIAOwAKAAoAZQB4AHAAbwByAHQAIABjAG8AbgBzAHQAIABmAG8AbwA6ACAARgBvAG8AIAA9ACAAMQA7AAoAZQB4AHAAbwByAHQAIABjAG8AbgBzAHQAIABiAGEAcgA6ACAAQgBhAHIAIAA9ACAAMgA7AAoA

### Expected result

It should remove the inline `type` keywords.

### Code of Conduct

- [X] I agree to follow Biome's Code of Conduct


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ac4765b877f8..b9b867f1e308 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -33,6 +33,8 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b
 
 ### Linter
 
+#### Bug Fixes
+
 - Biome no longer crashes when it encounters a string that contain a multibyte character ([#4181](https://github.com/biomejs/biome/issues/4181)).
 
   This fixes a regression introduced in Biome 1.9.3
@@ -49,6 +51,17 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b
 
 - Fix [#4041](https://github.com/biomejs/biome/issues/4041). Now the rule `useSortedClasses` won't be triggered if `className` is composed only by inlined variables. Contributed by @ematipico
 
+- [useImportType](https://biomejs.dev/linter/rules/use-import-type/) now reports useless inline type qualifiers ([#4178](https://github.com/biomejs/biome/issues/4178)).
+
+  The following fix is now proposed:
+
+  ```diff
+  - import type { type A, B } from "";
+  + import type { A, B } from "";
+  ```
+
+  Contributed by @Conaclos
+
 ### Parser
 
 #### Bug Fixes
diff --git a/crates/biome_js_analyze/src/lint/style/use_import_type.rs b/crates/biome_js_analyze/src/lint/style/use_import_type.rs
index 678fec49aa97..29b77ce026d5 100644
--- a/crates/biome_js_analyze/src/lint/style/use_import_type.rs
+++ b/crates/biome_js_analyze/src/lint/style/use_import_type.rs
@@ -136,10 +136,8 @@ impl Rule for UseImportType {
         if import_clause.assertion().is_some() {
             return None;
         }
-        if import_clause.type_token().is_some() ||
-            // Import attributes and type-only imports are not compatible.
-            import_clause.assertion().is_some()
-        {
+        // Import attributes and type-only imports are not compatible.
+        if import_clause.assertion().is_some() {
             return None;
         }
         let model = ctx.model();
@@ -157,7 +155,7 @@ impl Rule for UseImportType {
                 };
                 match clause.specifier().ok()? {
                     AnyJsCombinedSpecifier::JsNamedImportSpecifiers(named_specifiers) => {
-                        match named_import_type_fix(model, &named_specifiers) {
+                        match named_import_type_fix(model, &named_specifiers, false) {
                             Some(NamedImportTypeFix::UseImportType(specifiers)) => {
                                 if is_default_used_as_type {
                                     Some(ImportTypeFix::UseImportType)
@@ -180,6 +178,10 @@ impl Rule for UseImportType {
                                     Some(ImportTypeFix::AddInlineTypeQualifiers(specifiers))
                                 }
                             }
+                            Some(NamedImportTypeFix::RemoveInlineTypeQualifiers(_)) => {
+                                // Should not be reached because we pass `false` to `named_import_type_fix`.
+                                None
+                            }
                             None => is_default_used_as_type
                                 .then_some(ImportTypeFix::ExtractDefaultImportType(vec![])),
                         }
@@ -206,6 +208,9 @@ impl Rule for UseImportType {
                 }
             }
             AnyJsImportClause::JsImportDefaultClause(clause) => {
+                if clause.type_token().is_some() {
+                    return None;
+                }
                 let default_binding = clause.default_specifier().ok()?.local_name().ok()?;
                 let default_binding = default_binding.as_js_identifier_binding()?;
                 if ctx.jsx_runtime() == JsxRuntime::ReactClassic
@@ -217,14 +222,24 @@ impl Rule for UseImportType {
                 is_only_used_as_type(model, default_binding).then_some(ImportTypeFix::UseImportType)
             }
             AnyJsImportClause::JsImportNamedClause(clause) => {
-                match named_import_type_fix(model, &clause.named_specifiers().ok()?)? {
+                match named_import_type_fix(
+                    model,
+                    &clause.named_specifiers().ok()?,
+                    clause.type_token().is_some(),
+                )? {
                     NamedImportTypeFix::UseImportType(_) => Some(ImportTypeFix::UseImportType),
                     NamedImportTypeFix::AddInlineTypeQualifiers(specifiers) => {
                         Some(ImportTypeFix::AddInlineTypeQualifiers(specifiers))
                     }
+                    NamedImportTypeFix::RemoveInlineTypeQualifiers(type_tokens) => {
+                        Some(ImportTypeFix::RemoveTypeQualifiers(type_tokens))
+                    }
                 }
             }
             AnyJsImportClause::JsImportNamespaceClause(clause) => {
+                if clause.type_token().is_some() {
+                    return None;
+                }
                 let namespace_binding = clause.namespace_specifier().ok()?.local_name().ok()?;
                 let namespace_binding = namespace_binding.as_js_identifier_binding()?;
                 if ctx.jsx_runtime() == JsxRuntime::ReactClassic
@@ -300,6 +315,20 @@ impl Rule for UseImportType {
                 }
                 diagnostic
             }
+            ImportTypeFix::RemoveTypeQualifiers(type_tokens) => {
+                let mut diagnostic = RuleDiagnostic::new(
+                    rule_category!(),
+                    import.import_clause().ok()?.type_token()?.text_trimmed_range(),
+                    "The import has this type qualifier that makes all inline type qualifiers useless.",
+                );
+                for type_token in type_tokens {
+                    diagnostic = diagnostic.detail(
+                        type_token.text_trimmed_range(),
+                        "This inline type qualifier is useless.",
+                    )
+                }
+                return Some(diagnostic);
+            }
         };
         Some(diagnostic.note(markup! {
             "Importing the types with "<Emphasis>"import type"</Emphasis>" ensures that they are removed by the transpilers and avoids loading unnecessary modules."
@@ -527,6 +556,11 @@ impl Rule for UseImportType {
                     mutation.replace_node(specifier.clone(), new_specifier);
                 }
             }
+            ImportTypeFix::RemoveTypeQualifiers(type_tokens) => {
+                for type_token in type_tokens {
+                    mutation.remove_token(type_token.clone());
+                }
+            }
         }
         Some(JsRuleAction::new(
             ActionCategory::QuickFix,
@@ -543,6 +577,7 @@ pub enum ImportTypeFix {
     ExtractDefaultImportType(Vec<AnyJsNamedImportSpecifier>),
     ExtractCombinedImportType,
     AddInlineTypeQualifiers(Vec<AnyJsNamedImportSpecifier>),
+    RemoveTypeQualifiers(Vec<JsSyntaxToken>),
 }
 
 /// Returns `true` if all references of `binding` are only used as a type.
@@ -564,50 +599,71 @@ fn is_only_used_as_type(model: &SemanticModel, binding: &JsIdentifierBinding) ->
 pub enum NamedImportTypeFix {
     UseImportType(Vec<AnyJsNamedImportSpecifier>),
     AddInlineTypeQualifiers(Vec<AnyJsNamedImportSpecifier>),
+    RemoveInlineTypeQualifiers(Vec<JsSyntaxToken>),
 }
 
 fn named_import_type_fix(
     model: &SemanticModel,
     named_specifiers: &JsNamedImportSpecifiers,
+    has_type_token: bool,
 ) -> Option<NamedImportTypeFix> {
     let specifiers = named_specifiers.specifiers();
     if specifiers.is_empty() {
         return None;
     };
-    let mut imports_only_types = true;
-    let mut specifiers_requiring_type_marker = Vec::with_capacity(specifiers.len());
-    for specifier in specifiers.iter() {
-        let Ok(specifier) = specifier else {
-            imports_only_types = false;
-            continue;
-        };
-        if specifier.type_token().is_none() {
-            if specifier
-                .local_name()
-                .and_then(|local_name| {
-                    Some(is_only_used_as_type(
-                        model,
-                        local_name.as_js_identifier_binding()?,
-                    ))
-                })
-                .unwrap_or(false)
-            {
-                specifiers_requiring_type_marker.push(specifier);
-            } else {
-                imports_only_types = false;
+    if has_type_token {
+        let mut useless_type_tokens = Vec::with_capacity(specifiers.len());
+        for specifier in specifiers.iter() {
+            let Ok(specifier) = specifier else {
+                continue;
+            };
+            if let Some(type_token) = specifier.type_token() {
+                useless_type_tokens.push(type_token);
             }
         }
-    }
-    if imports_only_types {
-        Some(NamedImportTypeFix::UseImportType(
-            specifiers_requiring_type_marker,
-        ))
-    } else if specifiers_requiring_type_marker.is_empty() {
-        None
+        if useless_type_tokens.is_empty() {
+            None
+        } else {
+            Some(NamedImportTypeFix::RemoveInlineTypeQualifiers(
+                useless_type_tokens,
+            ))
+        }
     } else {
-        Some(NamedImportTypeFix::AddInlineTypeQualifiers(
-            specifiers_requiring_type_marker,
-        ))
+        let mut imports_only_types = true;
+        let mut specifiers_requiring_type_marker = Vec::with_capacity(specifiers.len());
+        for specifier in specifiers.iter() {
+            let Ok(specifier) = specifier else {
+                imports_only_types = false;
+                continue;
+            };
+            if specifier.type_token().is_none() {
+                if specifier
+                    .local_name()
+                    .and_then(|local_name| {
+                        Some(is_only_used_as_type(
+                            model,
+                            local_name.as_js_identifier_binding()?,
+                        ))
+                    })
+                    .unwrap_or(false)
+                {
+                    specifiers_requiring_type_marker.push(specifier);
+                } else {
+                    imports_only_types = false;
+                }
+            }
+        }
+        if imports_only_types {
+            Some(NamedImportTypeFix::UseImportType(
+                specifiers_requiring_type_marker,
+            ))
+        } else if specifiers_requiring_type_marker.is_empty() {
+            None
+        } else {
+            Some(NamedImportTypeFix::AddInlineTypeQualifiers(
+                specifiers_requiring_type_marker,
+            ))
+        }
     }
 }
 


Test patch:
diff --git a/crates/biome_js_analyze/tests/specs/style/useImportType/invalid-named-imports.ts b/crates/biome_js_analyze/tests/specs/style/useImportType/invalid-named-imports.ts
index b956804017cd..26589a020c15 100644
--- a/crates/biome_js_analyze/tests/specs/style/useImportType/invalid-named-imports.ts
+++ b/crates/biome_js_analyze/tests/specs/style/useImportType/invalid-named-imports.ts
@@ -9,11 +9,10 @@ import { X, Y } from "";
 type XX = X;
 const YY = Y;
 
-//import { type U, V } from "";
-//type VV = V;
+import { type H, type I, type J } from "";
+export type { H, I, J };
 
-import { type X, type Y, type Z } from "";
-export type { X, Y, Z };
+import type { type M, N, type O } from "";
 
 // multiline
 import {
diff --git a/crates/biome_js_analyze/tests/specs/style/useImportType/invalid-named-imports.ts.snap b/crates/biome_js_analyze/tests/specs/style/useImportType/invalid-named-imports.ts.snap
index 27f83ea298df..72d5c314de85 100644
--- a/crates/biome_js_analyze/tests/specs/style/useImportType/invalid-named-imports.ts.snap
+++ b/crates/biome_js_analyze/tests/specs/style/useImportType/invalid-named-imports.ts.snap
@@ -15,11 +15,10 @@ import { X, Y } from "";
 type XX = X;
 const YY = Y;
 
-//import { type U, V } from "";
-//type VV = V;
+import { type H, type I, type J } from "";
+export type { H, I, J };
 
-import { type X, type Y, type Z } from "";
-export type { X, Y, Z };
+import type { type M, N, type O } from "";
 
 // multiline
 import {
@@ -104,81 +103,116 @@ invalid-named-imports.ts:8:1 lint/style/useImportType  FIXABLE  ━━━━━
 ```
 
 ```
-invalid-named-imports.ts:15:1 lint/style/useImportType  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+invalid-named-imports.ts:12:1 lint/style/useImportType  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 
   ! All these imports are only used as types.
   
-    13 │ //type VV = V;
-    14 │ 
-  > 15 │ import { type X, type Y, type Z } from "";
+    10 │ const YY = Y;
+    11 │ 
+  > 12 │ import { type H, type I, type J } from "";
        │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-    16 │ export type { X, Y, Z };
-    17 │ 
+    13 │ export type { H, I, J };
+    14 │ 
   
   i Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
   
   i Safe fix: Use import type.
   
-    13 13 │   //type VV = V;
+    10 10 │   const YY = Y;
+    11 11 │   
+    12    │ - import·{·type·H,·type·I,·type·J·}·from·"";
+       12 │ + import·type·{·H,·I,·J·}·from·"";
+    13 13 │   export type { H, I, J };
     14 14 │   
-    15    │ - import·{·type·X,·type·Y,·type·Z·}·from·"";
-       15 │ + import·type·{·X,·Y,·Z·}·from·"";
-    16 16 │   export type { X, Y, Z };
-    17 17 │   
   
 
 ```
 
 ```
-invalid-named-imports.ts:19:1 lint/style/useImportType  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+invalid-named-imports.ts:15:8 lint/style/useImportType  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+  ! The import has this type qualifier that makes all inline type qualifiers useless.
+  
+    13 │ export type { H, I, J };
+    14 │ 
+  > 15 │ import type { type M, N, type O } from "";
+       │        ^^^^
+    16 │ 
+    17 │ // multiline
+  
+  i This inline type qualifier is useless.
+  
+    13 │ export type { H, I, J };
+    14 │ 
+  > 15 │ import type { type M, N, type O } from "";
+       │               ^^^^
+    16 │ 
+    17 │ // multiline
+  
+  i This inline type qualifier is useless.
+  
+    13 │ export type { H, I, J };
+    14 │ 
+  > 15 │ import type { type M, N, type O } from "";
+       │                          ^^^^
+    16 │ 
+    17 │ // multiline
+  
+  i Safe fix: Use import type.
+  
+    15 │ import·type·{·type·M,·N,·type·O·}·from·"";
+       │               -----      -----            
+
+```
+
+```
+invalid-named-imports.ts:18:1 lint/style/useImportType  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 
   ! Some named imports are only used as types.
   
-    18 │ // multiline
-  > 19 │ import {
+    17 │ // multiline
+  > 18 │ import {
        │ ^^^^^^^^
-  > 20 │     U,
-  > 21 │     V,
-  > 22 │     // leading comment
-  > 23 │     W,
-  > 24 │ } from "";
+  > 19 │     U,
+  > 20 │     V,
+  > 21 │     // leading comment
+  > 22 │     W,
+  > 23 │ } from "";
        │ ^^^^^^^^^^
-    25 │ export { U, type V, type W };
-    26 │ 
+    24 │ export { U, type V, type W };
+    25 │ 
   
   i This import is only used as a type.
   
-    19 │ import {
-    20 │     U,
-  > 21 │     V,
+    18 │ import {
+    19 │     U,
+  > 20 │     V,
        │     ^
-    22 │     // leading comment
-    23 │     W,
+    21 │     // leading comment
+    22 │     W,
   
   i This import is only used as a type.
   
-    21 │     V,
-    22 │     // leading comment
-  > 23 │     W,
+    20 │     V,
+    21 │     // leading comment
+  > 22 │     W,
        │     ^
-    24 │ } from "";
-    25 │ export { U, type V, type W };
+    23 │ } from "";
+    24 │ export { U, type V, type W };
   
   i Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
   
   i Safe fix: Use import type.
   
-    19 19 │   import {
-    20 20 │       U,
-    21    │ - ····V,
-       21 │ + ····type·V,
-    22 22 │       // leading comment
-    23    │ - ····W,
-       23 │ + ····type·W,
-    24 24 │   } from "";
-    25 25 │   export { U, type V, type W };
+    18 18 │   import {
+    19 19 │       U,
+    20    │ - ····V,
+       20 │ + ····type·V,
+    21 21 │       // leading comment
+    22    │ - ····W,
+       22 │ + ····type·W,
+    23 23 │   } from "";
+    24 24 │   export { U, type V, type W };
   
 
 ```
-
-
diff --git a/crates/biome_js_analyze/tests/specs/style/useImportType/valid-named-imports.ts b/crates/biome_js_analyze/tests/specs/style/useImportType/valid-named-imports.ts
index 7ffbbfade399..6e0384de814a 100644
--- a/crates/biome_js_analyze/tests/specs/style/useImportType/valid-named-imports.ts
+++ b/crates/biome_js_analyze/tests/specs/style/useImportType/valid-named-imports.ts
@@ -13,3 +13,10 @@ export type { C };
 
 import { D } from "";
 let a: D = new D();
+
+import { type E, F } from "";
+export type { E };
+export { F };
+
+import type { G } from "";
+export type { G };
diff --git a/crates/biome_js_analyze/tests/specs/style/useImportType/valid-named-imports.ts.snap b/crates/biome_js_analyze/tests/specs/style/useImportType/valid-named-imports.ts.snap
index 6ef270364b09..2d9fb077771c 100644
--- a/crates/biome_js_analyze/tests/specs/style/useImportType/valid-named-imports.ts.snap
+++ b/crates/biome_js_analyze/tests/specs/style/useImportType/valid-named-imports.ts.snap
@@ -20,6 +20,11 @@ export type { C };
 import { D } from "";
 let a: D = new D();
 
-```
+import { type E, F } from "";
+export type { E };
+export { F };
 
+import type { G } from "";
+export type { G };
 
+```