@@ -241,7 +241,7 @@ export function createImportAdder(sourceFile: SourceFile | FutureSourceFile, pro
241241interface AddToExistingState {
242242 readonly importClauseOrBindingPattern : ImportClause | ObjectBindingPattern ;
243243 defaultImport : Import | undefined ;
244- readonly namedImports : Map < string , AddAsTypeOnly > ;
244+ readonly namedImports : Map < string , { addAsTypeOnly : AddAsTypeOnly ; propertyName ?: string | undefined ; } > ;
245245}
246246
247247function createImportAdderWorker ( sourceFile : SourceFile | FutureSourceFile , program : Program , useAutoImportProvider : boolean , preferences : UserPreferences , host : LanguageServiceHost , cancellationToken : CancellationToken | undefined ) : ImportAdder {
@@ -290,15 +290,28 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog
290290 let fix = getImportFixForSymbol ( sourceFile , exportInfo , program , /*position*/ undefined , ! ! isValidTypeOnlyUseSite , useRequire , host , preferences ) ;
291291 if ( fix ) {
292292 const localName = tryCast ( referenceImport ?. name , isIdentifier ) ?. text ?? symbolName ;
293+ let addAsTypeOnly : AddAsTypeOnly | undefined ;
294+ let propertyName : string | undefined ;
293295 if (
294296 referenceImport
295297 && isTypeOnlyImportDeclaration ( referenceImport )
296298 && ( fix . kind === ImportFixKind . AddNew || fix . kind === ImportFixKind . AddToExisting )
297299 && fix . addAsTypeOnly === AddAsTypeOnly . Allowed
298300 ) {
299301 // Copy the type-only status from the reference import
300- fix = { ... fix , addAsTypeOnly : AddAsTypeOnly . Required } ;
302+ addAsTypeOnly = AddAsTypeOnly . Required ;
301303 }
304+
305+ if ( exportedSymbol . name !== localName ) {
306+ // checks if the symbol was aliased at the referenced import
307+ propertyName = exportedSymbol . name ;
308+ }
309+
310+ fix = {
311+ ...fix ,
312+ ...( addAsTypeOnly === undefined ? { } : { addAsTypeOnly } ) ,
313+ ...( propertyName === undefined ? { } : { propertyName } ) ,
314+ } ;
302315 addImport ( { fix, symbolName : localName ?? symbolName , errorIdentifierText : undefined } ) ;
303316 }
304317 }
@@ -375,14 +388,14 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog
375388 importType . push ( fix ) ;
376389 break ;
377390 case ImportFixKind . AddToExisting : {
378- const { importClauseOrBindingPattern, importKind, addAsTypeOnly } = fix ;
391+ const { importClauseOrBindingPattern, importKind, addAsTypeOnly, propertyName } = fix ;
379392 let entry = addToExisting . get ( importClauseOrBindingPattern ) ;
380393 if ( ! entry ) {
381394 addToExisting . set ( importClauseOrBindingPattern , entry = { importClauseOrBindingPattern, defaultImport : undefined , namedImports : new Map ( ) } ) ;
382395 }
383396 if ( importKind === ImportKind . Named ) {
384- const prevValue = entry ?. namedImports . get ( symbolName ) ;
385- entry . namedImports . set ( symbolName , reduceAddAsTypeOnlyValues ( prevValue , addAsTypeOnly ) ) ;
397+ const prevTypeOnly = entry ?. namedImports . get ( symbolName ) ?. addAsTypeOnly ;
398+ entry . namedImports . set ( symbolName , { addAsTypeOnly : reduceAddAsTypeOnlyValues ( prevTypeOnly , addAsTypeOnly ) , propertyName } ) ;
386399 }
387400 else {
388401 Debug . assert ( entry . defaultImport === undefined || entry . defaultImport . name === symbolName , "(Add to Existing) Default import should be missing or match symbolName" ) ;
@@ -394,7 +407,7 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog
394407 break ;
395408 }
396409 case ImportFixKind . AddNew : {
397- const { moduleSpecifier, importKind, useRequire, addAsTypeOnly } = fix ;
410+ const { moduleSpecifier, importKind, useRequire, addAsTypeOnly, propertyName } = fix ;
398411 const entry = getNewImportEntry ( moduleSpecifier , importKind , useRequire , addAsTypeOnly ) ;
399412 Debug . assert ( entry . useRequire === useRequire , "(Add new) Tried to add an `import` and a `require` for the same module" ) ;
400413
@@ -405,12 +418,12 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog
405418 break ;
406419 case ImportKind . Named :
407420 const prevValue = ( entry . namedImports ||= new Map ( ) ) . get ( symbolName ) ;
408- entry . namedImports . set ( symbolName , reduceAddAsTypeOnlyValues ( prevValue , addAsTypeOnly ) ) ;
421+ entry . namedImports . set ( symbolName , [ reduceAddAsTypeOnlyValues ( prevValue , addAsTypeOnly ) , propertyName ] ) ;
409422 break ;
410423 case ImportKind . CommonJS :
411424 if ( compilerOptions . verbatimModuleSyntax ) {
412425 const prevValue = ( entry . namedImports ||= new Map ( ) ) . get ( symbolName ) ;
413- entry . namedImports . set ( symbolName , reduceAddAsTypeOnlyValues ( prevValue , addAsTypeOnly ) ) ;
426+ entry . namedImports . set ( symbolName , [ reduceAddAsTypeOnlyValues ( prevValue , addAsTypeOnly ) , propertyName ] ) ;
414427 }
415428 else {
416429 Debug . assert ( entry . namespaceLikeImport === undefined || entry . namespaceLikeImport . name === symbolName , "Namespacelike import shoudl be missing or match symbolName" ) ;
@@ -582,7 +595,7 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog
582595 sourceFile as SourceFile ,
583596 importClauseOrBindingPattern ,
584597 defaultImport ,
585- arrayFrom ( namedImports . entries ( ) , ( [ name , addAsTypeOnly ] ) => ( { addAsTypeOnly, name } ) ) ,
598+ arrayFrom ( namedImports . entries ( ) , ( [ name , { addAsTypeOnly, propertyName } ] ) => ( { addAsTypeOnly, propertyName , name } ) ) ,
586599 importSpecifiersToRemoveWhileAdding ,
587600 preferences ,
588601 ) ;
@@ -596,7 +609,7 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog
596609 moduleSpecifier ,
597610 quotePreference ,
598611 defaultImport ,
599- namedImports && arrayFrom ( namedImports . entries ( ) , ( [ name , addAsTypeOnly ] ) => ( { addAsTypeOnly, name } ) ) ,
612+ namedImports && arrayFrom ( namedImports . entries ( ) , ( [ name , [ addAsTypeOnly , propertyName ] ] ) => ( { addAsTypeOnly, propertyName , name } ) ) ,
600613 namespaceLikeImport ,
601614 compilerOptions ,
602615 preferences ,
@@ -772,11 +785,13 @@ interface FixAddToExistingImport extends ImportFixBase {
772785 readonly importClauseOrBindingPattern : ImportClause | ObjectBindingPattern ;
773786 readonly importKind : ImportKind . Default | ImportKind . Named ;
774787 readonly addAsTypeOnly : AddAsTypeOnly ;
788+ readonly propertyName ?: string ;
775789}
776790interface FixAddNewImport extends ImportFixBase {
777791 readonly kind : ImportFixKind . AddNew ;
778792 readonly importKind : ImportKind ;
779793 readonly addAsTypeOnly : AddAsTypeOnly ;
794+ readonly propertyName ?: string ;
780795 readonly useRequire : boolean ;
781796 readonly qualification ?: Qualification ;
782797}
@@ -1794,7 +1809,7 @@ function doAddExistingFix(
17941809 factory . createObjectBindingPattern ( [
17951810 ...clause . elements . filter ( e => ! removeExistingImportSpecifiers . has ( e ) ) ,
17961811 ...defaultImport ? [ factory . createBindingElement ( /*dotDotDotToken*/ undefined , /*propertyName*/ "default" , defaultImport . name ) ] : emptyArray ,
1797- ...namedImports . map ( i => factory . createBindingElement ( /*dotDotDotToken*/ undefined , /* propertyName*/ undefined , i . name ) ) ,
1812+ ...namedImports . map ( i => factory . createBindingElement ( /*dotDotDotToken*/ undefined , i . propertyName , i . name ) ) ,
17981813 ] ) ,
17991814 ) ;
18001815 return ;
@@ -1803,7 +1818,7 @@ function doAddExistingFix(
18031818 addElementToBindingPattern ( clause , defaultImport . name , "default" ) ;
18041819 }
18051820 for ( const specifier of namedImports ) {
1806- addElementToBindingPattern ( clause , specifier . name , /* propertyName*/ undefined ) ;
1821+ addElementToBindingPattern ( clause , specifier . name , specifier . propertyName ) ;
18071822 }
18081823 return ;
18091824 }
@@ -1823,7 +1838,7 @@ function doAddExistingFix(
18231838 namedImports . map ( namedImport =>
18241839 factory . createImportSpecifier (
18251840 ( ! clause . isTypeOnly || promoteFromTypeOnly ) && shouldUseTypeOnly ( namedImport , preferences ) ,
1826- /* propertyName*/ undefined ,
1841+ namedImport . propertyName === undefined ? undefined : factory . createIdentifier ( namedImport . propertyName ) ,
18271842 factory . createIdentifier ( namedImport . name ) ,
18281843 )
18291844 ) ,
@@ -1919,11 +1934,12 @@ function getImportTypePrefix(moduleSpecifier: string, quotePreference: QuotePref
19191934interface Import {
19201935 readonly name : string ;
19211936 readonly addAsTypeOnly : AddAsTypeOnly ;
1937+ readonly propertyName ?: string ; // Use when needing to generate an `ImportSpecifier with a `propertyName`; the name preceding "as" keyword (undefined when "as" is absent)
19221938}
19231939
19241940interface ImportsCollection {
19251941 readonly defaultImport ?: Import ;
1926- readonly namedImports ?: Map < string , AddAsTypeOnly > ;
1942+ readonly namedImports ?: Map < string , [ AddAsTypeOnly , /*propertyName*/ string ? ] > ;
19271943 readonly namespaceLikeImport ?: {
19281944 readonly importKind : ImportKind . CommonJS | ImportKind . Namespace ;
19291945 readonly name : string ;
@@ -1964,7 +1980,7 @@ function getNewImports(
19641980 namedImports ?. map ( namedImport =>
19651981 factory . createImportSpecifier (
19661982 ! topLevelTypeOnly && shouldUseTypeOnly ( namedImport , preferences ) ,
1967- /* propertyName*/ undefined ,
1983+ namedImport . propertyName === undefined ? undefined : factory . createIdentifier ( namedImport . propertyName ) ,
19681984 factory . createIdentifier ( namedImport . name ) ,
19691985 )
19701986 ) ,
@@ -2003,7 +2019,7 @@ function getNewRequires(moduleSpecifier: string, quotePreference: QuotePreferenc
20032019 let statements : RequireVariableStatement | readonly RequireVariableStatement [ ] | undefined ;
20042020 // const { default: foo, bar, etc } = require('./mod');
20052021 if ( defaultImport || namedImports ?. length ) {
2006- const bindingElements = namedImports ?. map ( ( { name } ) => factory . createBindingElement ( /*dotDotDotToken*/ undefined , /* propertyName*/ undefined , name ) ) || [ ] ;
2022+ const bindingElements = namedImports ?. map ( ( { name, propertyName } ) => factory . createBindingElement ( /*dotDotDotToken*/ undefined , propertyName , name ) ) || [ ] ;
20072023 if ( defaultImport ) {
20082024 bindingElements . unshift ( factory . createBindingElement ( /*dotDotDotToken*/ undefined , "default" , defaultImport . name ) ) ;
20092025 }
0 commit comments