-
Notifications
You must be signed in to change notification settings - Fork 12.4k
/
convertToTypeOnlyImport.ts
53 lines (49 loc) · 2.77 KB
/
convertToTypeOnlyImport.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/* @internal */
namespace ts.codefix {
const errorCodes = [Diagnostics.This_import_is_never_used_as_a_value_and_must_use_import_type_because_importsNotUsedAsValues_is_set_to_error.code];
const fixId = "convertToTypeOnlyImport";
registerCodeFix({
errorCodes,
getCodeActions: function getCodeActionsToConvertToTypeOnlyImport(context) {
const changes = textChanges.ChangeTracker.with(context, t => {
const importDeclaration = getImportDeclarationForDiagnosticSpan(context.span, context.sourceFile);
fixSingleImportDeclaration(t, importDeclaration, context);
});
if (changes.length) {
return [createCodeFixAction(fixId, changes, Diagnostics.Convert_to_type_only_import, fixId, Diagnostics.Convert_all_imports_not_used_as_a_value_to_type_only_imports)];
}
},
fixIds: [fixId],
getAllCodeActions: function getAllCodeActionsToConvertToTypeOnlyImport(context) {
return codeFixAll(context, errorCodes, (changes, diag) => {
const importDeclaration = getImportDeclarationForDiagnosticSpan(diag, context.sourceFile);
fixSingleImportDeclaration(changes, importDeclaration, context);
});
}
});
function getImportDeclarationForDiagnosticSpan(span: TextSpan, sourceFile: SourceFile) {
return tryCast(getTokenAtPosition(sourceFile, span.start).parent, isImportDeclaration);
}
function fixSingleImportDeclaration(changes: textChanges.ChangeTracker, importDeclaration: ImportDeclaration | undefined, context: CodeFixContextBase) {
if (!importDeclaration?.importClause) {
return;
}
const { importClause } = importDeclaration;
// `changes.insertModifierBefore` produces a range that might overlap further changes
changes.insertText(context.sourceFile, importDeclaration.getStart() + "import".length, " type");
// `import type foo, { Bar }` is not allowed, so move `foo` to new declaration
if (importClause.name && importClause.namedBindings) {
changes.deleteNodeRangeExcludingEnd(context.sourceFile, importClause.name, importDeclaration.importClause.namedBindings);
changes.insertNodeBefore(context.sourceFile, importDeclaration, factory.updateImportDeclaration(
importDeclaration,
/*decorators*/ undefined,
/*modifiers*/ undefined,
factory.createImportClause(
/*isTypeOnly*/ true,
importClause.name,
/*namedBindings*/ undefined),
importDeclaration.moduleSpecifier,
/*assertClause*/ undefined));
}
}
}