@@ -31,7 +31,7 @@ export function elideImports(
31
31
// Collect all imports and used identifiers
32
32
const specialCaseNames = new Set < string > ( ) ;
33
33
const usedSymbols = new Set < ts . Symbol > ( ) ;
34
- const imports = [ ] as ts . ImportDeclaration [ ] ;
34
+ const imports : ts . ImportDeclaration [ ] = [ ] ;
35
35
ts . forEachChild ( sourceFile , function visit ( node ) {
36
36
// Skip removed nodes
37
37
if ( removedNodes . includes ( node ) ) {
@@ -84,28 +84,45 @@ export function elideImports(
84
84
continue ;
85
85
}
86
86
87
- if ( node . importClause . name ) {
88
- // "import XYZ from 'abc';"
89
- if ( isUnused ( node . importClause . name ) ) {
90
- ops . push ( new RemoveNodeOperation ( sourceFile , node ) ) ;
91
- }
92
- } else if ( node . importClause . namedBindings
93
- && ts . isNamespaceImport ( node . importClause . namedBindings ) ) {
87
+ const namedBindings = node . importClause . namedBindings ;
88
+
89
+ if ( namedBindings && ts . isNamespaceImport ( namedBindings ) ) {
94
90
// "import * as XYZ from 'abc';"
95
- if ( isUnused ( node . importClause . namedBindings . name ) ) {
91
+ if ( isUnused ( namedBindings . name ) ) {
96
92
ops . push ( new RemoveNodeOperation ( sourceFile , node ) ) ;
97
93
}
98
- } else if ( node . importClause . namedBindings
99
- && ts . isNamedImports ( node . importClause . namedBindings ) ) {
100
- // "import { XYZ, ... } from 'abc';"
94
+ } else {
101
95
const specifierOps = [ ] ;
102
- for ( const specifier of node . importClause . namedBindings . elements ) {
103
- if ( isUnused ( specifier . name ) ) {
104
- specifierOps . push ( new RemoveNodeOperation ( sourceFile , specifier ) ) ;
96
+ let clausesCount = 0 ;
97
+
98
+ // "import { XYZ, ... } from 'abc';"
99
+ if ( namedBindings && ts . isNamedImports ( namedBindings ) ) {
100
+ let removedClausesCount = 0 ;
101
+ clausesCount += namedBindings . elements . length ;
102
+
103
+ for ( const specifier of namedBindings . elements ) {
104
+ if ( isUnused ( specifier . name ) ) {
105
+ removedClausesCount ++ ;
106
+ // in case we don't have any more namedImports we should remove the parent ie the {}
107
+ const nodeToRemove = clausesCount === removedClausesCount
108
+ ? specifier . parent
109
+ : specifier ;
110
+
111
+ specifierOps . push ( new RemoveNodeOperation ( sourceFile , nodeToRemove ) ) ;
112
+ }
113
+ }
114
+ }
115
+
116
+ // "import XYZ from 'abc';"
117
+ if ( node . importClause . name ) {
118
+ clausesCount ++ ;
119
+
120
+ if ( isUnused ( node . importClause . name ) ) {
121
+ specifierOps . push ( new RemoveNodeOperation ( sourceFile , node . importClause . name ) ) ;
105
122
}
106
123
}
107
124
108
- if ( specifierOps . length === node . importClause . namedBindings . elements . length ) {
125
+ if ( specifierOps . length === clausesCount ) {
109
126
ops . push ( new RemoveNodeOperation ( sourceFile , node ) ) ;
110
127
} else {
111
128
ops . push ( ...specifierOps ) ;
0 commit comments