diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts
index 1fa19379afc4c..06db03c71b4cc 100644
--- a/src/services/textChanges.ts
+++ b/src/services/textChanges.ts
@@ -1275,7 +1275,15 @@ namespace changesToText {
const targetSourceFile = c.kind === ChangeKind.ReplaceWithSingleNode ? getSourceFileOfNode(getOriginalNode(c.node)) ?? c.sourceFile :
c.kind === ChangeKind.ReplaceWithMultipleNodes ? getSourceFileOfNode(getOriginalNode(c.nodes[0])) ?? c.sourceFile :
c.sourceFile;
- const newText = computeNewText(c, targetSourceFile, sourceFile, newLineCharacter, formatContext, validate);
+ let newText = computeNewText(c, targetSourceFile, sourceFile, newLineCharacter, formatContext, validate);
+
+ // prevent appending an extra new line to declarations at end of a file
+ const spanTextEnd = span.start + newText.length;
+ const isEndOfFile = span.length !== 0 && (spanTextEnd - newLineCharacter.length) === targetSourceFile.text.length;
+ if (c.kind === ChangeKind.ReplaceWithMultipleNodes && isEndOfFile && endsWith(newText, newLineCharacter)) {
+ newText = newText.substring(0, newText.length - newLineCharacter.length);
+ }
+
// Filter out redundant changes.
if (span.length === newText.length && stringContainsAt(targetSourceFile.text, newText, span.start)) {
return undefined;
diff --git a/tests/baselines/reference/organizeImports/TypeOnly.ts b/tests/baselines/reference/organizeImports/TypeOnly.ts
index 96281b4ada53a..d98ebcb23af35 100644
--- a/tests/baselines/reference/organizeImports/TypeOnly.ts
+++ b/tests/baselines/reference/organizeImports/TypeOnly.ts
@@ -12,4 +12,4 @@ import type Y from "lib";
import type { A, B } from "lib";
import { X, Z } from "lib";
-export { A, B, X, Y, Z };
+export { A, B, X, Y, Z };
\ No newline at end of file
diff --git a/tests/cases/fourslash/organizeImports12.ts b/tests/cases/fourslash/organizeImports12.ts
index 04b0e0214eac7..5b1d978f898c7 100644
--- a/tests/cases/fourslash/organizeImports12.ts
+++ b/tests/cases/fourslash/organizeImports12.ts
@@ -9,5 +9,5 @@
verify.organizeImports(
`declare export default class A {}
declare export * from "foo";
-declare export { a, b };
-`);
+declare export { a, b };`
+);
diff --git a/tests/cases/fourslash/organizeImports17.ts b/tests/cases/fourslash/organizeImports17.ts
index a72a7a054e7a0..4b0e84e980d5a 100644
--- a/tests/cases/fourslash/organizeImports17.ts
+++ b/tests/cases/fourslash/organizeImports17.ts
@@ -5,8 +5,7 @@
verify.organizeImports(
`import { case, Insensitively, sorted } from "aardvark";
-import { Both } from "module-specifiers-unsorted";
-`,
+import { Both } from "module-specifiers-unsorted";`,
ts.OrganizeImportsMode.SortAndCombine,
{
organizeImportsIgnoreCase: "auto",
diff --git a/tests/cases/fourslash/organizeImports18.ts b/tests/cases/fourslash/organizeImports18.ts
index 12ee4ef6cac9f..acbad3a166458 100644
--- a/tests/cases/fourslash/organizeImports18.ts
+++ b/tests/cases/fourslash/organizeImports18.ts
@@ -29,5 +29,5 @@ export { C } from "./C";
export { bFuncA } from "./A";
export { bFuncB } from "./B";
-export { bFuncC } from "./C";
-`);
+export { bFuncC } from "./C";`
+);
diff --git a/tests/cases/fourslash/organizeImports19.ts b/tests/cases/fourslash/organizeImports19.ts
index c7d00c70059d8..9908e31021d45 100644
--- a/tests/cases/fourslash/organizeImports19.ts
+++ b/tests/cases/fourslash/organizeImports19.ts
@@ -17,5 +17,5 @@ const b = 1;
export { b };
const c = 1;
-export { c };
-`);
+export { c };`
+);
diff --git a/tests/cases/fourslash/organizeImports24.ts b/tests/cases/fourslash/organizeImports24.ts
new file mode 100644
index 0000000000000..de5f8e4329dbd
--- /dev/null
+++ b/tests/cases/fourslash/organizeImports24.ts
@@ -0,0 +1,9 @@
+///
+
+//// export * from './file2.js';
+//// export * from './file1.js';
+
+verify.organizeImports(
+`export * from './file1.js';
+export * from './file2.js';`
+);
diff --git a/tests/cases/fourslash/organizeImports25.ts b/tests/cases/fourslash/organizeImports25.ts
new file mode 100644
index 0000000000000..91a9c393b8022
--- /dev/null
+++ b/tests/cases/fourslash/organizeImports25.ts
@@ -0,0 +1,15 @@
+///
+
+//// export * from './file4.js';
+//// export * from './file3.js';
+////
+//// export * from './file2.js';
+//// export * from './file1.js';
+
+verify.organizeImports(
+`export * from './file3.js';
+export * from './file4.js';
+
+export * from './file1.js';
+export * from './file2.js';`
+);
diff --git a/tests/cases/fourslash/organizeImports26.ts b/tests/cases/fourslash/organizeImports26.ts
new file mode 100644
index 0000000000000..912180ebe1a3b
--- /dev/null
+++ b/tests/cases/fourslash/organizeImports26.ts
@@ -0,0 +1,11 @@
+///
+
+//// export * from './file1.js';
+//// export * from './file2.js';
+////
+
+verify.organizeImports(
+`export * from './file1.js';
+export * from './file2.js';
+`
+);
diff --git a/tests/cases/fourslash/organizeImportsType2.ts b/tests/cases/fourslash/organizeImportsType2.ts
index 57b2b4db26950..24b0a099e8e45 100644
--- a/tests/cases/fourslash/organizeImportsType2.ts
+++ b/tests/cases/fourslash/organizeImportsType2.ts
@@ -15,16 +15,14 @@ verify.organizeImports(
`type A = string;
type B = string;
const C = "hello";
-export { A, C, type B };
-`
+export { A, C, type B };`
);
verify.organizeImports(
`type A = string;
type B = string;
const C = "hello";
-export { A, type B, C };
-`,
+export { A, type B, C };`,
undefined,
{ organizeImportsTypeOrder : "inline" }
);
@@ -33,8 +31,7 @@ verify.organizeImports(
`type A = string;
type B = string;
const C = "hello";
-export { type B, A, C };
-`,
+export { type B, A, C };`,
undefined,
{ organizeImportsTypeOrder : "first" }
);
@@ -43,8 +40,7 @@ verify.organizeImports(
`type A = string;
type B = string;
const C = "hello";
-export { A, C, type B };
-`,
+export { A, C, type B };`,
undefined,
{ organizeImportsTypeOrder : "last" }
);
\ No newline at end of file