From 81859299b90f617f932d9c47a36ac3aca3b68ff7 Mon Sep 17 00:00:00 2001
From: o-m12a
Date: Mon, 17 Nov 2025 22:10:01 +0900
Subject: [PATCH] Fix misplacement of comments after arrow (#17421)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: fisker Cheung
---
changelog_unreleased/typescript/17421.md | 30 +++++++++
src/language-js/comments/handle-comments.js | 37 +++++++++++
.../__snapshots__/format.test.js.snap | 61 +++++++++++++++++++
.../typescript/arrow/comments/format.test.js | 1 +
.../typescript/arrow/comments/issue-11100.ts | 23 +++++++
5 files changed, 152 insertions(+)
create mode 100644 changelog_unreleased/typescript/17421.md
create mode 100644 tests/format/typescript/arrow/comments/__snapshots__/format.test.js.snap
create mode 100644 tests/format/typescript/arrow/comments/format.test.js
create mode 100644 tests/format/typescript/arrow/comments/issue-11100.ts
diff --git a/changelog_unreleased/typescript/17421.md b/changelog_unreleased/typescript/17421.md
new file mode 100644
index 000000000..71bdcdfad
--- /dev/null
+++ b/changelog_unreleased/typescript/17421.md
@@ -0,0 +1,30 @@
+#### Fix misplacement of comments after arrow (#17421 by @o-m12a, @t-mangoe)
+
+
+```ts
+// Input
+export const test = (): any => /* first line
+second line
+*/
+ null;
+
+// Prettier stable
+export const test = (): any /* first line
+second line
+*/ => null;
+
+// Prettier stable (Second format)
+SyntaxError: Unexpected token (1:22)
+> 1 | export const test = (): any /* first line
+ | ^
+ 2 | second line
+ 3 | */ => null;
+ 4 |
+
+// Prettier main
+export const test = (): any =>
+ /* first line
+second line
+*/
+ null;
+```
diff --git a/src/language-js/comments/handle-comments.js b/src/language-js/comments/handle-comments.js
index c2e28b6c9..ed46701fd 100644
--- a/src/language-js/comments/handle-comments.js
+++ b/src/language-js/comments/handle-comments.js
@@ -100,6 +100,7 @@ function handleEndOfLineComment(context) {
handleLastUnionElementInExpression,
handleLastBinaryOperatorOperand,
handleTSMappedTypeComments,
+ handleCommentAfterArrowExpression,
handlePropertySignatureComments,
handleBinaryCastExpressionComment,
].some((fn) => fn(context));
@@ -1147,6 +1148,42 @@ function handleBinaryCastExpressionComment({
}
}
+/**
+ * Handle a comment after an arrow, like:
+ * ```ts
+ * const test = (): any => /* first line
+ * second line
+ * *\/
+ * null;
+ * ```
+ *
+ * @param {CommentContext} context
+ * @returns {boolean}
+ */
+function handleCommentAfterArrowExpression({
+ comment,
+ enclosingNode,
+ followingNode,
+ precedingNode,
+}) {
+ if (!(enclosingNode && followingNode && precedingNode)) {
+ return false;
+ }
+
+ if (
+ enclosingNode.type === "ArrowFunctionExpression" &&
+ // @ts-expect-error -- Safe
+ enclosingNode.returnType === precedingNode &&
+ (precedingNode.type === "TSTypeAnnotation" ||
+ precedingNode.type === "TypeAnnotation")
+ ) {
+ addLeadingComment(followingNode, comment);
+ return true;
+ }
+
+ return false;
+}
+
/**
* @param {Node} node
* @returns {boolean}
diff --git a/tests/format/typescript/arrow/comments/__snapshots__/format.test.js.snap b/tests/format/typescript/arrow/comments/__snapshots__/format.test.js.snap
new file mode 100644
index 000000000..15d099d8f
--- /dev/null
+++ b/tests/format/typescript/arrow/comments/__snapshots__/format.test.js.snap
@@ -0,0 +1,61 @@
+// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
+
+exports[`issue-11100.ts format 1`] = `
+====================================options=====================================
+parsers: ["typescript", "flow"]
+printWidth: 80
+ | printWidth
+=====================================input======================================
+const fn3 = (): any => /*
+Multiple line
+*/
+null;
+
+const fn4 = (): any => /* single line */
+null;
+
+const fn5 = (): any /* single line */ =>
+null;
+
+const fn6 = (): any => // line comment
+null;
+
+const fn7 = (a) => /*
+Multiple line
+*/
+null;
+
+const fn8 = () => /*
+Multiple line
+*/
+null;
+
+=====================================output=====================================
+const fn3 = (): any =>
+ /*
+Multiple line
+*/
+ null;
+
+const fn4 = (): any => /* single line */ null;
+
+const fn5 = (): any /* single line */ => null;
+
+const fn6 = (): any =>
+ // line comment
+ null;
+
+const fn7 = (
+ a /*
+Multiple line
+*/,
+) => null;
+
+const fn8 = () =>
+ /*
+Multiple line
+*/
+ null;
+
+================================================================================
+`;
diff --git a/tests/format/typescript/arrow/comments/format.test.js b/tests/format/typescript/arrow/comments/format.test.js
new file mode 100644
index 000000000..0e7a632d1
--- /dev/null
+++ b/tests/format/typescript/arrow/comments/format.test.js
@@ -0,0 +1 @@
+runFormatTest(import.meta, ["typescript", "flow"]);
diff --git a/tests/format/typescript/arrow/comments/issue-11100.ts b/tests/format/typescript/arrow/comments/issue-11100.ts
new file mode 100644
index 000000000..3a63bcb72
--- /dev/null
+++ b/tests/format/typescript/arrow/comments/issue-11100.ts
@@ -0,0 +1,23 @@
+const fn3 = (): any => /*
+Multiple line
+*/
+null;
+
+const fn4 = (): any => /* single line */
+null;
+
+const fn5 = (): any /* single line */ =>
+null;
+
+const fn6 = (): any => // line comment
+null;
+
+const fn7 = (a) => /*
+Multiple line
+*/
+null;
+
+const fn8 = () => /*
+Multiple line
+*/
+null;