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;