Skip to content

Commit 6faeee4

Browse files
committed
Don’t remove imports that are used for module augmentation, just remove their import clauses
1 parent 0f15bda commit 6faeee4

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

src/services/organizeImports.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ namespace ts.OrganizeImports {
8989
const usedImports: ImportDeclaration[] = [];
9090

9191
for (const importDecl of oldImports) {
92-
const {importClause} = importDecl;
92+
const { importClause, moduleSpecifier } = importDecl;
9393

9494
if (!importClause) {
9595
// Imports without import clauses are assumed to be included for their side effects and are not removed.
@@ -125,6 +125,14 @@ namespace ts.OrganizeImports {
125125
if (name || namedBindings) {
126126
usedImports.push(updateImportDeclarationAndClause(importDecl, name, namedBindings));
127127
}
128+
// If a module is imported to be augmented, keep the import declaration, but without an import clause
129+
else if (hasModuleDeclarationMatchingSpecifier(sourceFile, moduleSpecifier)) {
130+
usedImports.push(createImportDeclaration(
131+
importDecl.decorators,
132+
importDecl.modifiers,
133+
/*importClause*/ undefined,
134+
moduleSpecifier));
135+
}
128136
}
129137

130138
return usedImports;
@@ -135,6 +143,14 @@ namespace ts.OrganizeImports {
135143
}
136144
}
137145

146+
function hasModuleDeclarationMatchingSpecifier(sourceFile: SourceFile, moduleSpecifier: Expression) {
147+
const moduleSpecifierText = isStringLiteral(moduleSpecifier) && moduleSpecifier.text;
148+
return isString(moduleSpecifierText) && some(sourceFile.statements, statement =>
149+
isModuleDeclaration(statement)
150+
&& isStringLiteral(statement.name)
151+
&& statement.name.text === moduleSpecifierText);
152+
}
153+
138154
function getExternalModuleName(specifier: Expression) {
139155
return specifier !== undefined && isStringLiteralLike(specifier)
140156
? specifier.text

src/testRunner/unittests/services/organizeImports.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
namespace ts {
2-
describe("unittests:: services:: Organize imports", () => {
2+
describe("unittests:: services:: organizeImports", () => {
33
describe("Sort imports", () => {
44
it("Sort - non-relative vs non-relative", () => {
55
assertSortsBefore(
@@ -347,8 +347,10 @@ import { } from "lib";
347347
{
348348
path: "/test.d.ts",
349349
content: `
350+
import foo from 'foo';
350351
import { Caseless } from 'caseless';
351352
353+
declare module 'foo' {}
352354
declare module 'caseless' {
353355
interface Caseless {
354356
test(name: KeyType): boolean;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// ==ORIGINAL==
2+
3+
import foo from 'foo';
4+
import { Caseless } from 'caseless';
5+
6+
declare module 'foo' {}
7+
declare module 'caseless' {
8+
interface Caseless {
9+
test(name: KeyType): boolean;
10+
}
11+
}
12+
// ==ORGANIZED==
13+
14+
import 'caseless';
15+
import 'foo';
16+
17+
declare module 'foo' {}
18+
declare module 'caseless' {
19+
interface Caseless {
20+
test(name: KeyType): boolean;
21+
}
22+
}

0 commit comments

Comments
 (0)