diff --git a/crates/oxc_isolated_declarations/src/scope.rs b/crates/oxc_isolated_declarations/src/scope.rs index 0b95dd3799594..242997fa930e3 100644 --- a/crates/oxc_isolated_declarations/src/scope.rs +++ b/crates/oxc_isolated_declarations/src/scope.rs @@ -179,6 +179,16 @@ impl<'a> Visit<'a> for ScopeTree<'a> { // ==================== TSTypeParameter ==================== + fn visit_ts_type_parameter(&mut self, it: &TSTypeParameter<'a>) { + self.add_type_binding(it.name.name.clone()); + if let Some(constraint) = &it.constraint { + self.visit_ts_type(constraint); + } + if let Some(default) = &it.default { + self.visit_ts_type(default); + } + } + /// ```ts /// function foo(x: T): T { /// ^^^ @@ -191,7 +201,7 @@ impl<'a> Visit<'a> for ScopeTree<'a> { /// until the end of the function. So we leave the scope in the parent node (Function) fn visit_ts_type_parameter_declaration(&mut self, decl: &TSTypeParameterDeclaration<'a>) { self.enter_scope(ScopeFlags::empty()); - walk_ts_type_parameter_declaration(self, decl); + decl.params.iter().for_each(|param| self.visit_ts_type_parameter(param)); // exit scope in parent AST node } @@ -267,13 +277,10 @@ impl<'a> Visit<'a> for ScopeTree<'a> { fn visit_ts_mapped_type(&mut self, ty: &TSMappedType<'a>) { // copy from walk_ts_mapped_type self.enter_scope(ScopeFlags::empty()); - self.add_type_binding(ty.type_parameter.name.name.clone()); + self.visit_ts_type_parameter(&ty.type_parameter); if let Some(name) = &ty.name_type { self.visit_ts_type(name); } - if let Some(constraint) = &ty.type_parameter.constraint { - self.visit_ts_type(constraint); - } if let Some(type_annotation) = &ty.type_annotation { self.visit_ts_type(type_annotation); } @@ -292,6 +299,6 @@ impl<'a> Visit<'a> for ScopeTree<'a> { fn visit_ts_infer_type(&mut self, ty: &TSInferType<'a>) { // copy from walk_ts_infer_type - self.add_type_binding(ty.type_parameter.name.name.clone()); + self.visit_ts_type_parameter(&ty.type_parameter); } } diff --git a/crates/oxc_isolated_declarations/tests/fixtures/eliminate-imports.ts b/crates/oxc_isolated_declarations/tests/fixtures/eliminate-imports.ts index d068215c24840..eccce3d1e016c 100644 --- a/crates/oxc_isolated_declarations/tests/fixtures/eliminate-imports.ts +++ b/crates/oxc_isolated_declarations/tests/fixtures/eliminate-imports.ts @@ -4,4 +4,8 @@ export interface A extends AExtend {} export class B extends BExtend {} export class C implements CImplements1, CImplements2 {} export function foo(this: ThisType1): void {} -export const bar: (this: ThisType2) => void = function() {} \ No newline at end of file +export const bar: (this: ThisType2) => void = function() {} + +import { type InferType1, type InferType2 } from 'infer'; + +export type F = X extends infer U extends InferType2 ? U : never \ No newline at end of file diff --git a/crates/oxc_isolated_declarations/tests/snapshots/eliminate-imports.snap b/crates/oxc_isolated_declarations/tests/snapshots/eliminate-imports.snap index 05c135e43b32a..ec55dd2d9e76f 100644 --- a/crates/oxc_isolated_declarations/tests/snapshots/eliminate-imports.snap +++ b/crates/oxc_isolated_declarations/tests/snapshots/eliminate-imports.snap @@ -10,3 +10,5 @@ export declare class B extends BExtend {} export declare class C implements CImplements1, CImplements2 {} export declare function foo(this: ThisType1 ): void; export declare const bar: (this: ThisType2 ) => void; +import { type InferType1, type InferType2 } from 'infer'; +export type F = X extends infer U extends InferType2 ? U : never;