@@ -53,9 +53,9 @@ namespace ts.codefix {
5353 const flags = quotePreference === QuotePreference . Single ? NodeBuilderFlags . UseSingleQuotesForStringLiteralType : undefined ;
5454 let typeNode = checker . typeToTypeNode ( type , enclosingDeclaration , flags , getNoopSymbolTrackerWithResolver ( context ) ) ;
5555 if ( importAdder ) {
56- const importableReference = tryGetAutoImportableReferenceFromImportTypeNode ( typeNode , type , scriptTarget ) ;
56+ const importableReference = tryGetAutoImportableReferenceFromTypeNode ( typeNode , scriptTarget ) ;
5757 if ( importableReference ) {
58- typeNode = importableReference . typeReference ;
58+ typeNode = importableReference . typeNode ;
5959 importSymbols ( importAdder , importableReference . symbols ) ;
6060 }
6161 }
@@ -75,9 +75,9 @@ namespace ts.codefix {
7575 ? [ allAccessors . firstAccessor , allAccessors . secondAccessor ]
7676 : [ allAccessors . firstAccessor ] ;
7777 if ( importAdder ) {
78- const importableReference = tryGetAutoImportableReferenceFromImportTypeNode ( typeNode , type , scriptTarget ) ;
78+ const importableReference = tryGetAutoImportableReferenceFromTypeNode ( typeNode , scriptTarget ) ;
7979 if ( importableReference ) {
80- typeNode = importableReference . typeReference ;
80+ typeNode = importableReference . typeNode ;
8181 importSymbols ( importAdder , importableReference . symbols ) ;
8282 }
8383 }
@@ -175,21 +175,20 @@ namespace ts.codefix {
175175 let type = signatureDeclaration . type ;
176176 if ( importAdder ) {
177177 if ( typeParameters ) {
178- const newTypeParameters = sameMap ( typeParameters , ( typeParameterDecl , i ) => {
179- const typeParameter = signature . typeParameters ! [ i ] ;
178+ const newTypeParameters = sameMap ( typeParameters , typeParameterDecl => {
180179 let constraint = typeParameterDecl . constraint ;
181180 let defaultType = typeParameterDecl . default ;
182181 if ( constraint ) {
183- const importableReference = tryGetAutoImportableReferenceFromImportTypeNode ( constraint , typeParameter . constraint , scriptTarget ) ;
182+ const importableReference = tryGetAutoImportableReferenceFromTypeNode ( constraint , scriptTarget ) ;
184183 if ( importableReference ) {
185- constraint = importableReference . typeReference ;
184+ constraint = importableReference . typeNode ;
186185 importSymbols ( importAdder , importableReference . symbols ) ;
187186 }
188187 }
189188 if ( defaultType ) {
190- const importableReference = tryGetAutoImportableReferenceFromImportTypeNode ( defaultType , typeParameter . default , scriptTarget ) ;
189+ const importableReference = tryGetAutoImportableReferenceFromTypeNode ( defaultType , scriptTarget ) ;
191190 if ( importableReference ) {
192- defaultType = importableReference . typeReference ;
191+ defaultType = importableReference . typeNode ;
193192 importSymbols ( importAdder , importableReference . symbols ) ;
194193 }
195194 }
@@ -204,12 +203,11 @@ namespace ts.codefix {
204203 typeParameters = setTextRange ( factory . createNodeArray ( newTypeParameters , typeParameters . hasTrailingComma ) , typeParameters ) ;
205204 }
206205 }
207- const newParameters = sameMap ( parameters , ( parameterDecl , i ) => {
208- const parameter = signature . parameters [ i ] ;
209- const importableReference = tryGetAutoImportableReferenceFromImportTypeNode ( parameterDecl . type , checker . getTypeAtLocation ( parameter . valueDeclaration ) , scriptTarget ) ;
206+ const newParameters = sameMap ( parameters , parameterDecl => {
207+ const importableReference = tryGetAutoImportableReferenceFromTypeNode ( parameterDecl . type , scriptTarget ) ;
210208 let type = parameterDecl . type ;
211209 if ( importableReference ) {
212- type = importableReference . typeReference ;
210+ type = importableReference . typeNode ;
213211 importSymbols ( importAdder , importableReference . symbols ) ;
214212 }
215213 return factory . updateParameterDeclaration (
@@ -227,9 +225,9 @@ namespace ts.codefix {
227225 parameters = setTextRange ( factory . createNodeArray ( newParameters , parameters . hasTrailingComma ) , parameters ) ;
228226 }
229227 if ( type ) {
230- const importableReference = tryGetAutoImportableReferenceFromImportTypeNode ( type , signature . resolvedReturnType , scriptTarget ) ;
228+ const importableReference = tryGetAutoImportableReferenceFromTypeNode ( type , scriptTarget ) ;
231229 if ( importableReference ) {
232- type = importableReference . typeReference ;
230+ type = importableReference . typeNode ;
233231 importSymbols ( importAdder , importableReference . symbols ) ;
234232 }
235233 }
@@ -286,10 +284,10 @@ namespace ts.codefix {
286284 export function typeToAutoImportableTypeNode ( checker : TypeChecker , importAdder : ImportAdder , type : Type , contextNode : Node , scriptTarget : ScriptTarget , flags ?: NodeBuilderFlags , tracker ?: SymbolTracker ) : TypeNode | undefined {
287285 const typeNode = checker . typeToTypeNode ( type , contextNode , flags , tracker ) ;
288286 if ( typeNode && isImportTypeNode ( typeNode ) ) {
289- const importableReference = tryGetAutoImportableReferenceFromImportTypeNode ( typeNode , type , scriptTarget ) ;
287+ const importableReference = tryGetAutoImportableReferenceFromTypeNode ( typeNode , scriptTarget ) ;
290288 if ( importableReference ) {
291289 importSymbols ( importAdder , importableReference . symbols ) ;
292- return importableReference . typeReference ;
290+ return importableReference . typeNode ;
293291 }
294292 }
295293 return typeNode ;
@@ -454,38 +452,32 @@ namespace ts.codefix {
454452 }
455453
456454 /**
457- * Given an ImportTypeNode 'import("./a").SomeType<import("./b").OtherType<...>>',
455+ * Given a type node containing 'import("./a").SomeType<import("./b").OtherType<...>>',
458456 * returns an equivalent type reference node with any nested ImportTypeNodes also replaced
459457 * with type references, and a list of symbols that must be imported to use the type reference.
460458 */
461- export function tryGetAutoImportableReferenceFromImportTypeNode ( importTypeNode : TypeNode | undefined , type : Type | undefined , scriptTarget : ScriptTarget ) {
462- if ( importTypeNode && isLiteralImportTypeNode ( importTypeNode ) && importTypeNode . qualifier && ( ! type || type . symbol ) ) {
463- // Symbol for the left-most thing after the dot
464- const firstIdentifier = getFirstIdentifier ( importTypeNode . qualifier ) ;
465- const name = getNameForExportedSymbol ( firstIdentifier . symbol , scriptTarget ) ;
466- const qualifier = name !== firstIdentifier . text
467- ? replaceFirstIdentifierOfEntityName ( importTypeNode . qualifier , factory . createIdentifier ( name ) )
468- : importTypeNode . qualifier ;
469-
470- const symbols = [ firstIdentifier . symbol ] ;
471- const typeArguments : TypeNode [ ] = [ ] ;
472- if ( importTypeNode . typeArguments ) {
473- importTypeNode . typeArguments . forEach ( arg => {
474- const ref = tryGetAutoImportableReferenceFromImportTypeNode ( arg , /*undefined*/ type , scriptTarget ) ;
475- if ( ref ) {
476- symbols . push ( ...ref . symbols ) ;
477- typeArguments . push ( ref . typeReference ) ;
478- }
479- else {
480- typeArguments . push ( arg ) ;
481- }
482- } ) ;
483- }
459+ export function tryGetAutoImportableReferenceFromTypeNode ( importTypeNode : TypeNode | undefined , scriptTarget : ScriptTarget ) {
460+ let symbols : Symbol [ ] | undefined ;
461+ const typeNode = visitNode ( importTypeNode , visit ) ;
462+ if ( symbols && typeNode ) {
463+ return { typeNode, symbols } ;
464+ }
484465
485- return {
486- symbols,
487- typeReference : factory . createTypeReferenceNode ( qualifier , typeArguments )
488- } ;
466+ function visit ( node : TypeNode ) : TypeNode ;
467+ function visit ( node : Node ) : Node {
468+ if ( isLiteralImportTypeNode ( node ) && node . qualifier ) {
469+ // Symbol for the left-most thing after the dot
470+ const firstIdentifier = getFirstIdentifier ( node . qualifier ) ;
471+ const name = getNameForExportedSymbol ( firstIdentifier . symbol , scriptTarget ) ;
472+ const qualifier = name !== firstIdentifier . text
473+ ? replaceFirstIdentifierOfEntityName ( node . qualifier , factory . createIdentifier ( name ) )
474+ : node . qualifier ;
475+
476+ symbols = append ( symbols , firstIdentifier . symbol ) ;
477+ const typeArguments = node . typeArguments ?. map ( visit ) ;
478+ return factory . createTypeReferenceNode ( qualifier , typeArguments ) ;
479+ }
480+ return visitEachChild ( node , visit , nullTransformationContext ) ;
489481 }
490482 }
491483
0 commit comments