diff --git a/changelog_unreleased/typescript/18109.md b/changelog_unreleased/typescript/18109.md index 1029f9034..d89e78357 100644 --- a/changelog_unreleased/typescript/18109.md +++ b/changelog_unreleased/typescript/18109.md @@ -30,3 +30,5 @@ type A = // comment | Baz2000 | BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong; ``` + +_This change applies to Flow syntax too_ diff --git a/changelog_unreleased/typescript/18110.md b/changelog_unreleased/typescript/18110.md new file mode 100644 index 000000000..68bbb140a --- /dev/null +++ b/changelog_unreleased/typescript/18110.md @@ -0,0 +1,57 @@ +#### Fix inconsistent comment printing between `typescript` and `flow` parser (#18110 by @fisker) + + +```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; +} +``` diff --git a/src/language-js/comments/handle-comments.js b/src/language-js/comments/handle-comments.js index c0779edb0..7467059be 100644 --- a/src/language-js/comments/handle-comments.js +++ b/src/language-js/comments/handle-comments.js @@ -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} diff --git a/src/language-js/comments/printer-methods.js b/src/language-js/comments/printer-methods.js index a3bc7f412..179aa4c8e 100644 --- a/src/language-js/comments/printer-methods.js +++ b/src/language-js/comments/printer-methods.js @@ -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; } diff --git a/tests/config/run-format-test.js b/tests/config/run-format-test.js index 3aeef86da..e9e1cedce 100644 --- a/tests/config/run-format-test.js +++ b/tests/config/run-format-test.js @@ -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 diff --git a/tests/format/typescript/property-signature/consistent-with-flow/__snapshots__/format.test.js.snap b/tests/format/typescript/property-signature/consistent-with-flow/__snapshots__/format.test.js.snap new file mode 100644 index 000000000..e78c4752b --- /dev/null +++ b/tests/format/typescript/property-signature/consistent-with-flow/__snapshots__/format.test.js.snap @@ -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]; +} + +================================================================================ +`; diff --git a/tests/format/typescript/property-signature/consistent-with-flow/comments.ts b/tests/format/typescript/property-signature/consistent-with-flow/comments.ts new file mode 100644 index 000000000..f4c22795b --- /dev/null +++ b/tests/format/typescript/property-signature/consistent-with-flow/comments.ts @@ -0,0 +1,8 @@ +interface A { + property: // Comment + B +} + +interface A { + property: /* Comment */ B +} diff --git a/tests/format/typescript/property-signature/consistent-with-flow/format.test.js b/tests/format/typescript/property-signature/consistent-with-flow/format.test.js new file mode 100644 index 000000000..0e7a632d1 --- /dev/null +++ b/tests/format/typescript/property-signature/consistent-with-flow/format.test.js @@ -0,0 +1 @@ +runFormatTest(import.meta, ["typescript", "flow"]); diff --git a/tests/format/typescript/property-signature/consistent-with-flow/intersection.ts b/tests/format/typescript/property-signature/consistent-with-flow/intersection.ts new file mode 100644 index 000000000..f0c8a6786 --- /dev/null +++ b/tests/format/typescript/property-signature/consistent-with-flow/intersection.ts @@ -0,0 +1,7 @@ +export interface DirectiveArgumentNode extends ArrayExpression { + elements: // dir, exp, arg, modifiers + & [string] + & [string, ExpressionNode] + & [string, ExpressionNode, ExpressionNode] + & [string, ExpressionNode, ExpressionNode, ObjectExpression] +} diff --git a/tests/format/typescript/property-signature/consistent-with-flow/union.ts b/tests/format/typescript/property-signature/consistent-with-flow/union.ts new file mode 100644 index 000000000..17fdb8470 --- /dev/null +++ b/tests/format/typescript/property-signature/consistent-with-flow/union.ts @@ -0,0 +1,7 @@ +export interface DirectiveArgumentNode extends ArrayExpression { + elements: // dir, exp, arg, modifiers + | [string] + | [string, ExpressionNode] + | [string, ExpressionNode, ExpressionNode] + | [string, ExpressionNode, ExpressionNode, ObjectExpression] +}