diff --git a/crates/oxc_transformer/src/typescript/annotations.rs b/crates/oxc_transformer/src/typescript/annotations.rs index d321921602d68..7b35111bdd7f3 100644 --- a/crates/oxc_transformer/src/typescript/annotations.rs +++ b/crates/oxc_transformer/src/typescript/annotations.rs @@ -1,6 +1,6 @@ use rustc_hash::FxHashSet; -use oxc_allocator::Vec as ArenaVec; +use oxc_allocator::{CloneIn, Vec as ArenaVec}; use oxc_ast::ast::*; use oxc_diagnostics::OxcDiagnostic; use oxc_semantic::SymbolFlags; @@ -95,31 +95,49 @@ impl<'a, 'ctx> Traverse<'a> for TypeScriptAnnotations<'a, 'ctx> { Statement::ImportDeclaration(decl) => { if decl.import_kind.is_type() { false - } else if self.only_remove_type_imports { - true } else if let Some(specifiers) = &mut decl.specifiers { if specifiers.is_empty() { // import {} from 'mod' -> import 'mod' decl.specifiers = None; true } else { + let mut all_specifiers_is_type = true; specifiers.retain(|specifier| { let id = match specifier { ImportDeclarationSpecifier::ImportSpecifier(s) => { if s.import_kind.is_type() { return false; } + all_specifiers_is_type = false; &s.local } ImportDeclarationSpecifier::ImportDefaultSpecifier(s) => { + all_specifiers_is_type = false; &s.local } ImportDeclarationSpecifier::ImportNamespaceSpecifier(s) => { + all_specifiers_is_type = false; &s.local } }; + // Should preserve `import x from 'x'`(x is unused) if only_remove_type_imports enable + if self.only_remove_type_imports { + return true; + } self.has_value_reference(&id.name, ctx) }); + // Should transform `import { type x } from 'x'`` to `import 'xx'` if only_remove_type_imports enable + if all_specifiers_is_type && self.only_remove_type_imports { + *decl = ctx.ast.alloc_import_declaration( + decl.span, + None, + decl.source.clone(), + None, + decl.with_clause.clone_in(ctx.ast.allocator), + decl.import_kind, + ); + return true; + } !specifiers.is_empty() } } else { diff --git a/tasks/transform_conformance/snapshots/babel.snap.md b/tasks/transform_conformance/snapshots/babel.snap.md index 35e84c82d74b6..ada27f3245ccb 100644 --- a/tasks/transform_conformance/snapshots/babel.snap.md +++ b/tasks/transform_conformance/snapshots/babel.snap.md @@ -1691,7 +1691,9 @@ after transform: [] rebuilt : ["require"] * imports/only-remove-type-imports/input.ts -x Output mismatch +Bindings mismatch: +after transform: ScopeId(0): ["H", "I", "I2", "J", "K1", "K2", "L1", "L2", "L3", "a", "b", "c2", "d", "d2", "e", "e4"] +rebuilt : ScopeId(0): ["L2", "a", "b", "c2", "d", "d2", "e", "e4"] * imports/property-signature/input.ts Bindings mismatch: @@ -1722,7 +1724,9 @@ after transform: ScopeId(0): ["Foo1", "Foo2"] rebuilt : ScopeId(0): [] * imports/type-only-import-specifier-4/input.ts -x Output mismatch +Bindings mismatch: +after transform: ScopeId(0): ["A"] +rebuilt : ScopeId(0): [] * lvalues/TSTypeParameterInstantiation/input.ts Symbol reference IDs mismatch for "AbstractClass":