Fix unstable comment print (#18395)

This commit is contained in:
fisker Cheung authored and GitHub committed 2025-12-02 03:24:17 +08:00
1 parent 7efb988c67
commit ca02b37489
7 files changed
+167 -7

No files matched your search

+27
View File
@@ -0,0 +1,27 @@
#### Fix unstable comment print in union type comments (#18395 by @fisker)
<!-- prettier-ignore -->
```tsx
// Input
type X = (A | B) & (
// comment
A | B
);
// Prettier stable (first format)
type X = (A | B) &
(// comment
A | B);
// Prettier stable (second format)
type X = (
| A
| B // comment
) &
(A | B);
// Prettier main
type X = (A | B) &
// comment
(A | B);
```
@@ -3,6 +3,7 @@ import {
hasNodeIgnoreComment,
isJsxElement,
isUnionType,
shouldUnionTypePrintOwnComments,
} from "../utilities/index.js";
/**
@@ -47,7 +48,15 @@ function willPrintOwnComments(path) {
return false;
}
return isJsxElement(node) || isUnionType(node);
if (isUnionType(node)) {
return shouldUnionTypePrintOwnComments(path);
}
if (isJsxElement(node)) {
return true;
}
return false;
}
export default willPrintOwnComments;
+12 -6
View File
@@ -19,9 +19,13 @@ import {
hasLeadingOwnLineComment,
isConditionalType,
isTypeAlias,
isUnionType,
shouldUnionTypePrintOwnComments,
} from "../utilities/index.js";
/**
@import {Doc} from "../../document/index.js";
*/
// `TSUnionType` and `UnionTypeAnnotation`
function printUnionType(path, options, print) {
const { node } = path;
@@ -78,11 +82,13 @@ function printUnionType(path, options, print) {
return printComments(path, printedType, options);
}, "types");
const { leading, trailing } =
// If it's `types` of union type, parent will print comment for us
path.key === "types" && isUnionType(path.parent)
? { leading: "", trailing: "" }
: printCommentsSeparately(path, options);
/** @type {Doc} */
let leading = "";
/** @type {Doc} */
let trailing = "";
if (shouldUnionTypePrintOwnComments(path)) {
({ leading, trailing } = printCommentsSeparately(path, options));
}
if (shouldHug) {
return [leading, join(" | ", printed), trailing];
+14
View File
@@ -1085,6 +1085,19 @@ const isTypeAlias = createTypeCheckFunction([
"TypeAlias",
]);
function shouldUnionTypePrintOwnComments({ key, parent }) {
if (
// If it's `types` of union type, parent will print comment for it
(key === "types" && isUnionType(parent)) ||
// Inside intersection type let the comment print outside of parentheses
(key === "types" && isIntersectionType(parent))
) {
return false;
}
return true;
}
export {
CommentCheckFlags,
createTypeCheckFunction,
@@ -1145,6 +1158,7 @@ export {
needsHardlineAfterDanglingComment,
shouldFlatten,
shouldPrintComma,
shouldUnionTypePrintOwnComments,
startsWithNoLookaheadToken,
};
export { default as isMeaningfulEmptyStatement } from "./is-meaningful-empty-statement.js";
+3
View File
@@ -155,6 +155,9 @@ function printDanglingComments(
return shouldIndent ? indent([hardline, doc]) : doc;
}
/**
@returns {{leading?: Doc, trailing?: Doc}}
*/
function printCommentsSeparately(path, options) {
const value = path.node;
if (!value) {
@@ -0,0 +1,31 @@
type A1 =
(
A | B // comment 1
) & (
// comment2
A | B
)
type A2 =
(
A | B // prettier-ignore
) & (
// prettier-ignore
A | B
)
type A1 =
// comment 1
(A | B)
& (
// comment2
A | B
)
type A1 =
// prettier-ignore
(A | B)
& (
// prettier-ignore
A | B
)
@@ -96,6 +96,76 @@ type A3 =
================================================================================
`;
exports[`18379.ts format 1`] = `
====================================options=====================================
parsers: ["typescript", "flow"]
printWidth: 80
| printWidth
=====================================input======================================
type A1 =
(
A | B // comment 1
) & (
// comment2
A | B
)
type A2 =
(
A | B // prettier-ignore
) & (
// prettier-ignore
A | B
)
type A1 =
// comment 1
(A | B)
& (
// comment2
A | B
)
type A1 =
// prettier-ignore
(A | B)
& (
// prettier-ignore
A | B
)
=====================================output=====================================
type A1 = (
| A
| B // comment 1
) &
// comment2
(A | B);
type A2 = (
| A
| B // prettier-ignore
) &
// prettier-ignore
(A | B);
type A1 =
// comment 1
(A | B) &
// comment2
(A | B);
type A1 =
// prettier-ignore
(A | B)
& (
// prettier-ignore
A | B
);
================================================================================
`;
exports[`18389.ts format 1`] = `
====================================options=====================================
parsers: ["typescript", "flow"]