fix(isolated-declarations): eliminate imports incorrectly when they are used in TSInferType (#4043)

close: #4018
This commit is contained in:
Dunqing 2024-07-03 15:32:27 +00:00
parent 5e5b1b14a1
commit 3d29e9cb75
3 changed files with 20 additions and 7 deletions

View file

@ -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<T>(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);
}
}

View file

@ -4,4 +4,8 @@ export interface A extends AExtend<Type> {}
export class B extends BExtend<Type> {}
export class C implements CImplements1<CType>, CImplements2<CType> {}
export function foo(this: ThisType1): void {}
export const bar: (this: ThisType2) => void = function() {}
export const bar: (this: ThisType2) => void = function() {}
import { type InferType1, type InferType2 } from 'infer';
export type F<X extends InferType1> = X extends infer U extends InferType2 ? U : never

View file

@ -10,3 +10,5 @@ export declare class B extends BExtend<Type> {}
export declare class C implements CImplements1<CType>, CImplements2<CType> {}
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 InferType1> = X extends infer U extends InferType2 ? U : never;