@@ -241,7 +241,7 @@ export function createImportAdder(sourceFile: SourceFile | FutureSourceFile, pro
241
241
interface AddToExistingState {
242
242
readonly importClauseOrBindingPattern : ImportClause | ObjectBindingPattern ;
243
243
defaultImport : Import | undefined ;
244
- readonly namedImports : Map < string , AddAsTypeOnly > ;
244
+ readonly namedImports : Map < string , { addAsTypeOnly : AddAsTypeOnly ; propertyName ?: string | undefined ; } > ;
245
245
}
246
246
247
247
function 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
290
290
let fix = getImportFixForSymbol ( sourceFile , exportInfo , program , /*position*/ undefined , ! ! isValidTypeOnlyUseSite , useRequire , host , preferences ) ;
291
291
if ( fix ) {
292
292
const localName = tryCast ( referenceImport ?. name , isIdentifier ) ?. text ?? symbolName ;
293
+ let addAsTypeOnly : AddAsTypeOnly | undefined ;
294
+ let propertyName : string | undefined ;
293
295
if (
294
296
referenceImport
295
297
&& isTypeOnlyImportDeclaration ( referenceImport )
296
298
&& ( fix . kind === ImportFixKind . AddNew || fix . kind === ImportFixKind . AddToExisting )
297
299
&& fix . addAsTypeOnly === AddAsTypeOnly . Allowed
298
300
) {
299
301
// Copy the type-only status from the reference import
300
- fix = { ... fix , addAsTypeOnly : AddAsTypeOnly . Required } ;
302
+ addAsTypeOnly = AddAsTypeOnly . Required ;
301
303
}
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
+ } ;
302
315
addImport ( { fix, symbolName : localName ?? symbolName , errorIdentifierText : undefined } ) ;
303
316
}
304
317
}
@@ -375,14 +388,14 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog
375
388
importType . push ( fix ) ;
376
389
break ;
377
390
case ImportFixKind . AddToExisting : {
378
- const { importClauseOrBindingPattern, importKind, addAsTypeOnly } = fix ;
391
+ const { importClauseOrBindingPattern, importKind, addAsTypeOnly, propertyName } = fix ;
379
392
let entry = addToExisting . get ( importClauseOrBindingPattern ) ;
380
393
if ( ! entry ) {
381
394
addToExisting . set ( importClauseOrBindingPattern , entry = { importClauseOrBindingPattern, defaultImport : undefined , namedImports : new Map ( ) } ) ;
382
395
}
383
396
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 } ) ;
386
399
}
387
400
else {
388
401
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
394
407
break ;
395
408
}
396
409
case ImportFixKind . AddNew : {
397
- const { moduleSpecifier, importKind, useRequire, addAsTypeOnly } = fix ;
410
+ const { moduleSpecifier, importKind, useRequire, addAsTypeOnly, propertyName } = fix ;
398
411
const entry = getNewImportEntry ( moduleSpecifier , importKind , useRequire , addAsTypeOnly ) ;
399
412
Debug . assert ( entry . useRequire === useRequire , "(Add new) Tried to add an `import` and a `require` for the same module" ) ;
400
413
@@ -405,12 +418,12 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog
405
418
break ;
406
419
case ImportKind . Named :
407
420
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 ] ) ;
409
422
break ;
410
423
case ImportKind . CommonJS :
411
424
if ( compilerOptions . verbatimModuleSyntax ) {
412
425
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 ] ) ;
414
427
}
415
428
else {
416
429
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
582
595
sourceFile as SourceFile ,
583
596
importClauseOrBindingPattern ,
584
597
defaultImport ,
585
- arrayFrom ( namedImports . entries ( ) , ( [ name , addAsTypeOnly ] ) => ( { addAsTypeOnly, name } ) ) ,
598
+ arrayFrom ( namedImports . entries ( ) , ( [ name , { addAsTypeOnly, propertyName } ] ) => ( { addAsTypeOnly, propertyName , name } ) ) ,
586
599
importSpecifiersToRemoveWhileAdding ,
587
600
preferences ,
588
601
) ;
@@ -596,7 +609,7 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog
596
609
moduleSpecifier ,
597
610
quotePreference ,
598
611
defaultImport ,
599
- namedImports && arrayFrom ( namedImports . entries ( ) , ( [ name , addAsTypeOnly ] ) => ( { addAsTypeOnly, name } ) ) ,
612
+ namedImports && arrayFrom ( namedImports . entries ( ) , ( [ name , [ addAsTypeOnly , propertyName ] ] ) => ( { addAsTypeOnly, propertyName , name } ) ) ,
600
613
namespaceLikeImport ,
601
614
compilerOptions ,
602
615
preferences ,
@@ -772,11 +785,13 @@ interface FixAddToExistingImport extends ImportFixBase {
772
785
readonly importClauseOrBindingPattern : ImportClause | ObjectBindingPattern ;
773
786
readonly importKind : ImportKind . Default | ImportKind . Named ;
774
787
readonly addAsTypeOnly : AddAsTypeOnly ;
788
+ readonly propertyName ?: string ;
775
789
}
776
790
interface FixAddNewImport extends ImportFixBase {
777
791
readonly kind : ImportFixKind . AddNew ;
778
792
readonly importKind : ImportKind ;
779
793
readonly addAsTypeOnly : AddAsTypeOnly ;
794
+ readonly propertyName ?: string ;
780
795
readonly useRequire : boolean ;
781
796
readonly qualification ?: Qualification ;
782
797
}
@@ -1794,7 +1809,7 @@ function doAddExistingFix(
1794
1809
factory . createObjectBindingPattern ( [
1795
1810
...clause . elements . filter ( e => ! removeExistingImportSpecifiers . has ( e ) ) ,
1796
1811
...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 ) ) ,
1798
1813
] ) ,
1799
1814
) ;
1800
1815
return ;
@@ -1803,7 +1818,7 @@ function doAddExistingFix(
1803
1818
addElementToBindingPattern ( clause , defaultImport . name , "default" ) ;
1804
1819
}
1805
1820
for ( const specifier of namedImports ) {
1806
- addElementToBindingPattern ( clause , specifier . name , /* propertyName*/ undefined ) ;
1821
+ addElementToBindingPattern ( clause , specifier . name , specifier . propertyName ) ;
1807
1822
}
1808
1823
return ;
1809
1824
}
@@ -1823,7 +1838,7 @@ function doAddExistingFix(
1823
1838
namedImports . map ( namedImport =>
1824
1839
factory . createImportSpecifier (
1825
1840
( ! clause . isTypeOnly || promoteFromTypeOnly ) && shouldUseTypeOnly ( namedImport , preferences ) ,
1826
- /* propertyName*/ undefined ,
1841
+ namedImport . propertyName === undefined ? undefined : factory . createIdentifier ( namedImport . propertyName ) ,
1827
1842
factory . createIdentifier ( namedImport . name ) ,
1828
1843
)
1829
1844
) ,
@@ -1919,11 +1934,12 @@ function getImportTypePrefix(moduleSpecifier: string, quotePreference: QuotePref
1919
1934
interface Import {
1920
1935
readonly name : string ;
1921
1936
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)
1922
1938
}
1923
1939
1924
1940
interface ImportsCollection {
1925
1941
readonly defaultImport ?: Import ;
1926
- readonly namedImports ?: Map < string , AddAsTypeOnly > ;
1942
+ readonly namedImports ?: Map < string , [ AddAsTypeOnly , /*propertyName*/ string ? ] > ;
1927
1943
readonly namespaceLikeImport ?: {
1928
1944
readonly importKind : ImportKind . CommonJS | ImportKind . Namespace ;
1929
1945
readonly name : string ;
@@ -1964,7 +1980,7 @@ function getNewImports(
1964
1980
namedImports ?. map ( namedImport =>
1965
1981
factory . createImportSpecifier (
1966
1982
! topLevelTypeOnly && shouldUseTypeOnly ( namedImport , preferences ) ,
1967
- /* propertyName*/ undefined ,
1983
+ namedImport . propertyName === undefined ? undefined : factory . createIdentifier ( namedImport . propertyName ) ,
1968
1984
factory . createIdentifier ( namedImport . name ) ,
1969
1985
)
1970
1986
) ,
@@ -2003,7 +2019,7 @@ function getNewRequires(moduleSpecifier: string, quotePreference: QuotePreferenc
2003
2019
let statements : RequireVariableStatement | readonly RequireVariableStatement [ ] | undefined ;
2004
2020
// const { default: foo, bar, etc } = require('./mod');
2005
2021
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 ) ) || [ ] ;
2007
2023
if ( defaultImport ) {
2008
2024
bindingElements . unshift ( factory . createBindingElement ( /*dotDotDotToken*/ undefined , "default" , defaultImport . name ) ) ;
2009
2025
}
0 commit comments