@@ -150,5 +150,52 @@ export default defineConfig({
150150 ts . forEachChild ( node , visit ) ;
151151 } ) ;
152152 } ,
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+ } ,
153200 } ,
154201} ) ;
0 commit comments