Don’t touch imports used for module augmentation in non-declaration files since it could change JS emit

This commit is contained in:
Andrew Branch 2019-05-22 11:37:35 -07:00
parent 6faeee449d
commit 60d0bb9b19
No known key found for this signature in database
GPG Key ID: 22CCA4B120C427D2
3 changed files with 55 additions and 10 deletions

View File

@ -125,13 +125,22 @@ namespace ts.OrganizeImports {
if (name || namedBindings) {
usedImports.push(updateImportDeclarationAndClause(importDecl, name, namedBindings));
}
// If a module is imported to be augmented, keep the import declaration, but without an import clause
// If a module is imported to be augmented, its used
else if (hasModuleDeclarationMatchingSpecifier(sourceFile, moduleSpecifier)) {
usedImports.push(createImportDeclaration(
importDecl.decorators,
importDecl.modifiers,
/*importClause*/ undefined,
moduleSpecifier));
// If were in a declaration file, its safe to remove the import clause from it
if (sourceFile.isDeclarationFile) {
usedImports.push(createImportDeclaration(
importDecl.decorators,
importDecl.modifiers,
/*importClause*/ undefined,
moduleSpecifier));
}
// If were not in a declaration file, we cant remove the import clause even though
// the imported symbols are unused, because removing them makes it look like the import
// declaration has side effects, which will cause it to be preserved in the JS emit.
else {
usedImports.push(importDecl);
}
}
}
@ -145,10 +154,9 @@ namespace ts.OrganizeImports {
function hasModuleDeclarationMatchingSpecifier(sourceFile: SourceFile, moduleSpecifier: Expression) {
const moduleSpecifierText = isStringLiteral(moduleSpecifier) && moduleSpecifier.text;
return isString(moduleSpecifierText) && some(sourceFile.statements, statement =>
isModuleDeclaration(statement)
&& isStringLiteral(statement.name)
&& statement.name.text === moduleSpecifierText);
return isString(moduleSpecifierText) && some(sourceFile.moduleAugmentations, moduleName =>
isStringLiteral(moduleName)
&& moduleName.text === moduleSpecifierText);
}
function getExternalModuleName(specifier: Expression) {

View File

@ -350,6 +350,21 @@ import { } from "lib";
import foo from 'foo';
import { Caseless } from 'caseless';
declare module 'foo' {}
declare module 'caseless' {
interface Caseless {
test(name: KeyType): boolean;
}
}`
});
testOrganizeImports("Unused_preserve_imports_for_module_augmentation_in_non_declaration_file",
{
path: "/test.ts",
content: `
import foo from 'foo';
import { Caseless } from 'caseless';
declare module 'foo' {}
declare module 'caseless' {
interface Caseless {

View File

@ -0,0 +1,22 @@
// ==ORIGINAL==
import foo from 'foo';
import { Caseless } from 'caseless';
declare module 'foo' {}
declare module 'caseless' {
interface Caseless {
test(name: KeyType): boolean;
}
}
// ==ORGANIZED==
import { Caseless } from 'caseless';
import foo from 'foo';
declare module 'foo' {}
declare module 'caseless' {
interface Caseless {
test(name: KeyType): boolean;
}
}