diff --git a/crates/oxc_transformer/src/typescript/annotations.rs b/crates/oxc_transformer/src/typescript/annotations.rs index d4594c79da9cc2..c10051397a3314 100644 --- a/crates/oxc_transformer/src/typescript/annotations.rs +++ b/crates/oxc_transformer/src/typescript/annotations.rs @@ -4,6 +4,7 @@ use std::{cell::Cell, rc::Rc}; use oxc_allocator::Vec as ArenaVec; use oxc_ast::ast::*; +use oxc_semantic::SymbolFlags; use oxc_span::{Atom, GetSpan, Span, SPAN}; use oxc_syntax::{ operator::AssignmentOperator, reference::ReferenceFlag, scope::ScopeFlags, symbol::SymbolId, @@ -496,6 +497,15 @@ impl<'a> TypeScriptAnnotations<'a> { pub fn has_value_reference(&self, name: &str, ctx: &TraverseCtx<'a>) -> bool { if let Some(symbol_id) = ctx.scopes().get_root_binding(name) { + // `import T from 'mod'; const T = 1;` The T has a value redeclaration + // `import T from 'mod'; type T = number;` The T has a type redeclaration + // If there is still a value symbol after SymbolFlags::Import is removed, then it's a value redeclaration. + // That means the import is shadowed, and we can safely remove the import. + let has_value_redeclaration = + (ctx.symbols().get_flag(symbol_id) - SymbolFlags::Import).is_value(); + if has_value_redeclaration { + return false; + } if ctx .symbols() .get_resolved_references(symbol_id) diff --git a/tasks/transform_conformance/oxc.snap.md b/tasks/transform_conformance/oxc.snap.md index a520ee4c368b42..5c8247a1d141f9 100644 --- a/tasks/transform_conformance/oxc.snap.md +++ b/tasks/transform_conformance/oxc.snap.md @@ -1,6 +1,6 @@ commit: 12619ffe -Passed: 7/7 +Passed: 8/8 # All Passed: * babel-plugin-transform-typescript diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-typescript/test/fixtures/redeclarations/input.ts b/tasks/transform_conformance/tests/babel-plugin-transform-typescript/test/fixtures/redeclarations/input.ts new file mode 100644 index 00000000000000..71e25715aa5522 --- /dev/null +++ b/tasks/transform_conformance/tests/babel-plugin-transform-typescript/test/fixtures/redeclarations/input.ts @@ -0,0 +1,15 @@ +// CASE 1: redeclaration of VariableDeclaration +import { A } from './a'; +const A: A = 0; +export {A}; + +// CASE 2: redeclaration of TypeAlias +import { T } from "./t"; +type T = number; +export { T } + +// CASE 3: redeclaration of VariableDeclaration and TypeAlias +import { B } from './b'; +const B: B = 0; +type B = number; +export { B } \ No newline at end of file diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-typescript/test/fixtures/redeclarations/output.js b/tasks/transform_conformance/tests/babel-plugin-transform-typescript/test/fixtures/redeclarations/output.js new file mode 100644 index 00000000000000..cd77114c9598b2 --- /dev/null +++ b/tasks/transform_conformance/tests/babel-plugin-transform-typescript/test/fixtures/redeclarations/output.js @@ -0,0 +1,12 @@ +// CASE 1: redeclaration of VariableDeclaration +const A = 0; +export { A }; + +// CASE 2: redeclaration of TypeAlias +import { T } from "./t"; +export { T }; + +// CASE 3: redeclaration of VariableDeclaration and TypeAlias +const B = 0; +export { B }; +