Fix inconsistent comment in property signature (#18110)

This commit is contained in:
fisker Cheung authored and GitHub committed 2025-10-21 17:40:46 +08:00
1 parent 64a0ea62bb
commit d4bd42f7f4
10 files changed
+198

No files matched your search

+2
View File
@@ -30,3 +30,5 @@ type A = // comment
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
```
_This change applies to Flow syntax too_
+57
View File
@@ -0,0 +1,57 @@
#### Fix inconsistent comment printing between `typescript` and `flow` parser (#18110 by @fisker)
<!-- prettier-ignore -->
```tsx
// Input
interface A {
a: // Comment
B;
b: // Comment
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
c: // Comment
& Fooo1000
& Baz2000
& BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
}
// Prettier stable (--parser=typescript)
interface A {
a: // Comment
B;
b: // Comment
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
c: // Comment
Fooo1000 &
Baz2000 &
BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
}
// Prettier stable (--parser=flow)
interface A {
a: B; // Comment
b: // Comment
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
c: Fooo1000 & // Comment
Baz2000 &
BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
}
// Prettier main (Same output for `--parser=typescript` and `--parser=flow`)
interface A {
a: B; // Comment
b: // Comment
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
c: // Comment
Fooo1000 &
Baz2000 &
BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
}
```
@@ -98,6 +98,7 @@ function handleEndOfLineComment(context) {
handleLastUnionElementInExpression,
handleLastBinaryOperatorOperand,
handleTSMappedTypeComments,
handlePropertySignatureComments,
].some((fn) => fn(context));
}
@@ -1102,6 +1103,22 @@ function handleLastBinaryOperatorOperand({
return false;
}
function handlePropertySignatureComments({
enclosingNode,
followingNode,
comment,
}) {
if (
enclosingNode &&
(enclosingNode.type === "TSPropertySignature" ||
enclosingNode.type === "ObjectTypeProperty") &&
isIntersectionType(followingNode)
) {
addLeadingComment(followingNode, comment);
return true;
}
}
/**
* @param {Node} node
* @returns {boolean}
@@ -97,6 +97,24 @@ function canAttachComment(node, ancestors) {
return isMeaningfulEmptyStatement({ node, parent: ancestors[0] });
}
/*
For this code
`interface A {property: B}`
^ `ObjectTypeProperty.value` (Flow)
`interface A {property: B}`
^^^ `TSPropertySignature.typeAnnotation` (TypeScript)
^ `TSPropertySignature.typeAnnotation.typeAnnotation` (TypeScript)
```
To avoid inconsistent, let's attach to the Identifier instead.
*/
if (
node.type === "TSTypeAnnotation" &&
ancestors[0].type === "TSPropertySignature"
) {
return false;
}
return true;
}
+1
View File
@@ -49,6 +49,7 @@ const unstableTests = new Map(
["js/ignore/semi/asi.js", (options) => options.semi === false],
"typescript/union/consistent-with-flow/single-type.ts",
"js/if/non-block.js",
"typescript/import-type/long-module-name/long-module-name4.ts",
].map((fixture) => {
const [file, isUnstable = () => true] = Array.isArray(fixture)
? fixture
@@ -0,0 +1,80 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`comments.ts format 1`] = `
====================================options=====================================
parsers: ["typescript", "flow"]
printWidth: 80
| printWidth
=====================================input======================================
interface A {
property: // Comment
B
}
interface A {
property: /* Comment */ B
}
=====================================output=====================================
interface A {
property: B; // Comment
}
interface A {
property: /* Comment */ B;
}
================================================================================
`;
exports[`intersection.ts format 1`] = `
====================================options=====================================
parsers: ["typescript", "flow"]
printWidth: 80
| printWidth
=====================================input======================================
export interface DirectiveArgumentNode extends ArrayExpression {
elements: // dir, exp, arg, modifiers
& [string]
& [string, ExpressionNode]
& [string, ExpressionNode, ExpressionNode]
& [string, ExpressionNode, ExpressionNode, ObjectExpression]
}
=====================================output=====================================
export interface DirectiveArgumentNode extends ArrayExpression {
elements: // dir, exp, arg, modifiers
[string] &
[string, ExpressionNode] &
[string, ExpressionNode, ExpressionNode] &
[string, ExpressionNode, ExpressionNode, ObjectExpression];
}
================================================================================
`;
exports[`union.ts format 1`] = `
====================================options=====================================
parsers: ["typescript", "flow"]
printWidth: 80
| printWidth
=====================================input======================================
export interface DirectiveArgumentNode extends ArrayExpression {
elements: // dir, exp, arg, modifiers
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression]
}
=====================================output=====================================
export interface DirectiveArgumentNode extends ArrayExpression {
elements: // dir, exp, arg, modifiers
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression];
}
================================================================================
`;
@@ -0,0 +1,8 @@
interface A {
property: // Comment
B
}
interface A {
property: /* Comment */ B
}
@@ -0,0 +1 @@
runFormatTest(import.meta, ["typescript", "flow"]);
@@ -0,0 +1,7 @@
export interface DirectiveArgumentNode extends ArrayExpression {
elements: // dir, exp, arg, modifiers
& [string]
& [string, ExpressionNode]
& [string, ExpressionNode, ExpressionNode]
& [string, ExpressionNode, ExpressionNode, ObjectExpression]
}
@@ -0,0 +1,7 @@
export interface DirectiveArgumentNode extends ArrayExpression {
elements: // dir, exp, arg, modifiers
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression]
}