@@ -150,5 +150,52 @@ export default defineConfig({
150
150
ts . forEachChild ( node , visit ) ;
151
151
} ) ;
152
152
} ,
153
+ 'type-imports' ( { typescript : ts , file, report } ) {
154
+ ts . forEachChild ( file , function visit ( node ) {
155
+ if (
156
+ ts . isImportDeclaration ( node )
157
+ && node . importClause
158
+ && node . importClause . namedBindings
159
+ && node . importClause . phaseModifier !== ts . SyntaxKind . TypeKeyword
160
+ && ! node . importClause . name
161
+ && ! ts . isNamespaceImport ( node . importClause . namedBindings )
162
+ && node . importClause . namedBindings . elements . every ( e => e . isTypeOnly )
163
+ ) {
164
+ const typeElements = node . importClause . namedBindings . elements ;
165
+ report (
166
+ 'This import statement should use type-only import.' ,
167
+ node . getStart ( file ) ,
168
+ node . getEnd ( ) ,
169
+ ) . withFix (
170
+ 'Replace inline type imports with a type-only import.' ,
171
+ ( ) => [
172
+ {
173
+ fileName : file . fileName ,
174
+ textChanges : [
175
+ ...typeElements . map ( element => {
176
+ const token = element . getFirstToken ( file ) ! ;
177
+ return {
178
+ newText : '' ,
179
+ span : {
180
+ start : token . getStart ( file ) ,
181
+ length : element . name . getStart ( file ) - token . getStart ( file ) ,
182
+ } ,
183
+ } ;
184
+ } ) ,
185
+ {
186
+ newText : 'type ' ,
187
+ span : {
188
+ start : node . importClause ! . getStart ( file ) ,
189
+ length : 0 ,
190
+ } ,
191
+ } ,
192
+ ] ,
193
+ } ,
194
+ ] ,
195
+ ) ;
196
+ }
197
+ ts . forEachChild ( node , visit ) ;
198
+ } ) ;
199
+ } ,
153
200
} ,
154
201
} ) ;
0 commit comments