diff --git a/changelog_unreleased/typescript/19410.md b/changelog_unreleased/typescript/19410.md new file mode 100644 index 000000000..0ecd3806f --- /dev/null +++ b/changelog_unreleased/typescript/19410.md @@ -0,0 +1,22 @@ +#### Preserve comment position after `=` in type alias declarations (#19410 by @WhoamiI00) + + +```ts +// Input +type A = + /* 1 */ | /* 2 */ ( + /* 3 */ | /* 4 */ { + key: string; + } + ); + +// Prettier stable +type A /* 2 */ = /* 1 */ /* 3 */ /* 4 */ { + key: string; +}; + +// Prettier main +type A = /* 1 */ /* 2 */ /* 3 */ /* 4 */ { + key: string; +}; +``` diff --git a/src/language-js/comments/handle-comments.js b/src/language-js/comments/handle-comments.js index cd2d3e47f..8f21b1763 100644 --- a/src/language-js/comments/handle-comments.js +++ b/src/language-js/comments/handle-comments.js @@ -139,6 +139,7 @@ function handleRemainingComment(context) { handleParenthesizedExpressionTrailingComment, handleBinaryCastExpressionComment, handleUnionTypeLeadingComments, + handleAssignmentLikeAnnotationLeadingComments, ].some((fn) => fn(context)); } @@ -782,6 +783,28 @@ function handleVariableDeclaratorComments({ return false; } +function handleAssignmentLikeAnnotationLeadingComments({ + comment, + enclosingNode, + followingNode, + options, +}) { + if (isAssignmentLikeNode(enclosingNode) && followingNode) { + // @ts-expect-error -- Safe + const leftSide = enclosingNode.id ?? enclosingNode.left; + const equalsTokenIndex = stripComments(options).indexOf( + "=", + locEnd(leftSide), + ); + if (locStart(comment) >= equalsTokenIndex) { + addLeadingComment(followingNode, comment); + return true; + } + } + + return false; +} + function handleTSFunctionTrailingComments({ comment, enclosingNode, diff --git a/tests/config/format-test/failed-format-tests.js b/tests/config/format-test/failed-format-tests.js index dcd5eb733..816bef1bc 100644 --- a/tests/config/format-test/failed-format-tests.js +++ b/tests/config/format-test/failed-format-tests.js @@ -16,7 +16,6 @@ const unstableTests = new Map( (options) => options.proseWrap === "always", ], "flow/hook/declare-hook.js", - "flow/hook/comments-before-arrow.js", "flow/hook/hook-type-annotation.js", "flow/comments/type_annotations.js", "typescript/prettier-ignore/mapped-types.ts", diff --git a/tests/format/typescript/intersection/__snapshots__/format.test.js.snap b/tests/format/typescript/intersection/__snapshots__/format.test.js.snap index 8dbea8225..255fb306d 100644 --- a/tests/format/typescript/intersection/__snapshots__/format.test.js.snap +++ b/tests/format/typescript/intersection/__snapshots__/format.test.js.snap @@ -192,25 +192,25 @@ type A2 = C; type A3 = C; type A4 = C; type A5 = C; -type A6 /*1*/ = C; -type A7 /*1*/ = C; -type A8 /*1*/ = C; -type A9 /*1*/ = C; -type A10 /*1*/ = /*2*/ C; -type A11 /*1*/ = /*2*/ C; -type A12 /*1*/ = C; +type A6 = /*1*/ C; +type A7 = /*1*/ C; +type A8 = /*1*/ C; +type A9 = /*1*/ C; +type A10 = /*1*/ /*2*/ C; +type A11 = /*1*/ /*2*/ C; +type A12 = /*1*/ C; type A13 = /*1*/ C; type Aa1 = /*1*/ /*2*/ C & D; type Aa2 = /*1*/ /*2*/ C & /*3*/ D; type Aa3 = /*1*/ /*2*/ C & /*3*/ D /*4*/; -type C1 /*1*/ = a & b; -type C2 /*1*/ = a & b; -type C3 /*1*/ = a & b; -type C4 /*1*/ = a & b; -type C5 /*1*/ = a & b; -type C6 /*0*/ /*1*/ = a & b; +type C1 = /*1*/ a & b; +type C2 = /*1*/ a & b; +type C3 = /*1*/ a & b; +type C4 = /*1*/ a & b; +type C5 = /*1*/ a & b; +type C6 /*0*/ = /*1*/ a & b; type Ctor = (new () => X) & Y; @@ -409,25 +409,25 @@ type A2 = C type A3 = C type A4 = C type A5 = C -type A6 /*1*/ = C -type A7 /*1*/ = C -type A8 /*1*/ = C -type A9 /*1*/ = C -type A10 /*1*/ = /*2*/ C -type A11 /*1*/ = /*2*/ C -type A12 /*1*/ = C +type A6 = /*1*/ C +type A7 = /*1*/ C +type A8 = /*1*/ C +type A9 = /*1*/ C +type A10 = /*1*/ /*2*/ C +type A11 = /*1*/ /*2*/ C +type A12 = /*1*/ C type A13 = /*1*/ C type Aa1 = /*1*/ /*2*/ C & D type Aa2 = /*1*/ /*2*/ C & /*3*/ D type Aa3 = /*1*/ /*2*/ C & /*3*/ D /*4*/ -type C1 /*1*/ = a & b -type C2 /*1*/ = a & b -type C3 /*1*/ = a & b -type C4 /*1*/ = a & b -type C5 /*1*/ = a & b -type C6 /*0*/ /*1*/ = a & b +type C1 = /*1*/ a & b +type C2 = /*1*/ a & b +type C3 = /*1*/ a & b +type C4 = /*1*/ a & b +type C5 = /*1*/ a & b +type C6 /*0*/ = /*1*/ a & b type Ctor = (new () => X) & Y @@ -625,25 +625,25 @@ type A2 = C; type A3 = C; type A4 = C; type A5 = C; -type A6 /*1*/ = C; -type A7 /*1*/ = C; -type A8 /*1*/ = C; -type A9 /*1*/ = C; -type A10 /*1*/ = /*2*/ C; -type A11 /*1*/ = /*2*/ C; -type A12 /*1*/ = C; +type A6 = /*1*/ C; +type A7 = /*1*/ C; +type A8 = /*1*/ C; +type A9 = /*1*/ C; +type A10 = /*1*/ /*2*/ C; +type A11 = /*1*/ /*2*/ C; +type A12 = /*1*/ C; type A13 = /*1*/ C; type Aa1 = /*1*/ /*2*/ C & D; type Aa2 = /*1*/ /*2*/ C & /*3*/ D; type Aa3 = /*1*/ /*2*/ C & /*3*/ D /*4*/; -type C1 /*1*/ = a & b; -type C2 /*1*/ = a & b; -type C3 /*1*/ = a & b; -type C4 /*1*/ = a & b; -type C5 /*1*/ = a & b; -type C6 /*0*/ /*1*/ = a & b; +type C1 = /*1*/ a & b; +type C2 = /*1*/ a & b; +type C3 = /*1*/ a & b; +type C4 = /*1*/ a & b; +type C5 = /*1*/ a & b; +type C6 /*0*/ = /*1*/ a & b; type Ctor = (new () => X) & Y; diff --git a/tests/format/typescript/intersection/consistent-with-flow/__snapshots__/format.test.js.snap b/tests/format/typescript/intersection/consistent-with-flow/__snapshots__/format.test.js.snap index 2e22516f4..5419da062 100644 --- a/tests/format/typescript/intersection/consistent-with-flow/__snapshots__/format.test.js.snap +++ b/tests/format/typescript/intersection/consistent-with-flow/__snapshots__/format.test.js.snap @@ -91,24 +91,135 @@ type B2 = C; type B3 = C; type B4 = C; type B5 = C; -type B6 /*1*/ = C; -type B7 /*1*/ = C; -type B8 /*1*/ = C; -type B9 /*1*/ = C; -type B10 /*1*/ = /*2*/ C; -type B11 /*1*/ = /*2*/ C; -type B12 /*1*/ = C; +type B6 = /*1*/ C; +type B7 = /*1*/ C; +type B8 = /*1*/ C; +type B9 = /*1*/ C; +type B10 = /*1*/ /*2*/ C; +type B11 = /*1*/ /*2*/ C; +type B12 = /*1*/ C; type Bb1 = /*1*/ /*2*/ C & D; type Bb2 = /*1*/ /*2*/ C & /*3*/ D; type Bb3 = /*1*/ /*2*/ C & /*3*/ D /*4*/; -type D1 /*1*/ = a & b; -type D2 /*1*/ = a & b; -type D3 /*1*/ = a & b; -type D4 /*1*/ = a & b; -type D5 /*1*/ = a & b; -type D6 /*0*/ /*1*/ = a & b; +type D1 = /*1*/ a & b; +type D2 = /*1*/ a & b; +type D3 = /*1*/ a & b; +type D4 = /*1*/ a & b; +type D5 = /*1*/ a & b; +type D6 /*0*/ = /*1*/ a & b; + +================================================================================ +`; + +exports[`single-member.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript", "flow"] + printWidth: 80 (default) | +=====================================input====================================== +// https://github.com/oxc-project/oxc/pull/21915 + +// export type aType = & // Comment +// "VALUE"; + +export type bType = & +// Comment +"VALUE"; + +export type cType = & /* Comment */ +"VALUE"; + +export type dType = /* Comment */ +& "VALUE"; + +// export type eType = // Comment +// & "VALUE"; + +export type fType = & +/* Comment */ +"VALUE"; + +export type gType = & +// Comment +// Comment +"VALUE"; + +export type hType = & +"VALUE"; + +export type iType = /* Comment */ /* Comment */ & "VALUE"; + +export type jType = /* Comment */ +/* Comment */ & "VALUE"; + +export type kType = /* Comment */ +& +// Comment +"VALUE"; + +export type lType = /* Comment */ & +// Comment +"VALUE"; + +export type mType = & "VALUE" /* Comment */; + +export type nType = // Comment +& /* Comment */ +"VALUE"; + +// type oType = // Comment +// & // Comment +// "VALUE" + +=====================================output===================================== +// https://github.com/oxc-project/oxc/pull/21915 + +// export type aType = & // Comment +// "VALUE"; + +export type bType = + // Comment + "VALUE"; + +export type cType = /* Comment */ "VALUE"; + +export type dType = /* Comment */ "VALUE"; + +// export type eType = // Comment +// & "VALUE"; + +export type fType = + /* Comment */ + "VALUE"; + +export type gType = + // Comment + // Comment + "VALUE"; + +export type hType = "VALUE"; + +export type iType = /* Comment */ /* Comment */ "VALUE"; + +export type jType = /* Comment */ /* Comment */ "VALUE"; + +export type kType = + /* Comment */ + // Comment + "VALUE"; + +export type lType = + /* Comment */ // Comment + "VALUE"; + +export type mType = "VALUE"; /* Comment */ + +export type nType = /* Comment */ "VALUE"; // Comment + +// type oType = // Comment +// & // Comment +// "VALUE" ================================================================================ `; diff --git a/tests/format/typescript/intersection/consistent-with-flow/single-member.ts b/tests/format/typescript/intersection/consistent-with-flow/single-member.ts new file mode 100644 index 000000000..8b25ce496 --- /dev/null +++ b/tests/format/typescript/intersection/consistent-with-flow/single-member.ts @@ -0,0 +1,53 @@ +// https://github.com/oxc-project/oxc/pull/21915 + +// export type aType = & // Comment +// "VALUE"; + +export type bType = & +// Comment +"VALUE"; + +export type cType = & /* Comment */ +"VALUE"; + +export type dType = /* Comment */ +& "VALUE"; + +// export type eType = // Comment +// & "VALUE"; + +export type fType = & +/* Comment */ +"VALUE"; + +export type gType = & +// Comment +// Comment +"VALUE"; + +export type hType = & +"VALUE"; + +export type iType = /* Comment */ /* Comment */ & "VALUE"; + +export type jType = /* Comment */ +/* Comment */ & "VALUE"; + +export type kType = /* Comment */ +& +// Comment +"VALUE"; + +export type lType = /* Comment */ & +// Comment +"VALUE"; + +export type mType = & "VALUE" /* Comment */; + +export type nType = // Comment +& /* Comment */ +"VALUE"; + +// type oType = // Comment +// & // Comment +// "VALUE" diff --git a/tests/format/typescript/union/__snapshots__/format.test.js.snap b/tests/format/typescript/union/__snapshots__/format.test.js.snap index 7e53a5c56..316a9a20d 100644 --- a/tests/format/typescript/union/__snapshots__/format.test.js.snap +++ b/tests/format/typescript/union/__snapshots__/format.test.js.snap @@ -567,13 +567,13 @@ type A2 = C; type A3 = C; type A4 = C; type A5 = C; -type A6 /*1*/ = C; -type A7 /*1*/ = C; -type A8 /*1*/ = C; -type A9 /*1*/ = C; -type A10 /*1*/ = /*2*/ C; -type A11 /*1*/ = /*2*/ C; -type A12 /*1*/ = C; +type A6 = /*1*/ C; +type A7 = /*1*/ C; +type A8 = /*1*/ C; +type A9 = /*1*/ C; +type A10 = /*1*/ /*2*/ C; +type A11 = /*1*/ /*2*/ C; +type A12 = /*1*/ C; type A13 = /*1*/ C; type Aa1 = /*1*/ /*2*/ C | D; @@ -583,7 +583,7 @@ type Aa3 = /*1*/ /*2*/ C | /*3*/ D /*4*/; type C1 = /*1*/ a | b; type C2 = /*1*/ a | b; type C3 = /*1*/ a | b; -type C4 /*1*/ = a | b; +type C4 = /*1*/ a | b; type C5 = /*1*/ a | b; type C6 /*0*/ = /*1*/ a | b; diff --git a/tests/format/typescript/union/single-type/__snapshots__/format.test.js.snap b/tests/format/typescript/union/single-type/__snapshots__/format.test.js.snap index 1a767f61e..e57829c98 100644 --- a/tests/format/typescript/union/single-type/__snapshots__/format.test.js.snap +++ b/tests/format/typescript/union/single-type/__snapshots__/format.test.js.snap @@ -1,5 +1,34 @@ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing +exports[`comments.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript"] + printWidth: 80 (default) | +=====================================input====================================== +// https://github.com/prettier/prettier/issues/18834 +type A1 = /* 1 */ | T1; +type A2 = /* 1 */ | (T2); +type A3 = (/* 1 */ | T3); +type A4 = /* 1 */ | /* 2 */ T4; +type A5 = /* 1 */ | (/* 2 */ T5); +type A6 = /* 0 */ /* 1 */ | /* 2 */ T6; +type A7 = /* 0 */ | /* 1 */ T7; +type A8 /* = */ /* 1:before */ = /* 2 */ | /* 3 */ T7; + +=====================================output===================================== +// https://github.com/prettier/prettier/issues/18834 +type A1 = /* 1 */ T1; +type A2 = /* 1 */ T2; +type A3 = /* 1 */ T3; +type A4 = /* 1 */ /* 2 */ T4; +type A5 = /* 1 */ /* 2 */ T5; +type A6 = /* 0 */ /* 1 */ /* 2 */ T6; +type A7 = /* 0 */ /* 1 */ T7; +type A8 /* = */ /* 1:before */ = /* 2 */ /* 3 */ T7; + +================================================================================ +`; + exports[`single-type.ts format 1`] = ` ====================================options===================================== parsers: ["typescript"] @@ -13,9 +42,51 @@ type A1 = ); =====================================output===================================== -type A1 /* 2 */ = /* 1 */ /* 3 */ /* 4 */ { +type A1 = /* 1 */ /* 2 */ /* 3 */ /* 4 */ { key: string; }; ================================================================================ `; + +exports[`single-type-2.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript"] + printWidth: 80 (default) | +=====================================input====================================== +// https://github.com/oxc-project/oxc/pull/21915 +export type myType = | // Comment + "A"; + +// Block comment same-line after pipe +type BlockComment = | /* block */ + "B"; + +// Same-line comment then own-line comment +type Mixed = | // first + // second + "C"; + +// Long line comment that exceeds printWidth on the \`=\` line +type LongType = | // This is a really long comment that might exceed the print width limit + "A"; + +=====================================output===================================== +// https://github.com/oxc-project/oxc/pull/21915 +export type myType = // Comment + "A"; + +// Block comment same-line after pipe +type BlockComment = /* block */ "B"; + +// Same-line comment then own-line comment +type Mixed = // first + // second + "C"; + +// Long line comment that exceeds printWidth on the \`=\` line +type LongType = // This is a really long comment that might exceed the print width limit + "A"; + +================================================================================ +`; diff --git a/tests/format/typescript/union/single-type/comments.ts b/tests/format/typescript/union/single-type/comments.ts new file mode 100644 index 000000000..5aaf05b35 --- /dev/null +++ b/tests/format/typescript/union/single-type/comments.ts @@ -0,0 +1,9 @@ +// https://github.com/prettier/prettier/issues/18834 +type A1 = /* 1 */ | T1; +type A2 = /* 1 */ | (T2); +type A3 = (/* 1 */ | T3); +type A4 = /* 1 */ | /* 2 */ T4; +type A5 = /* 1 */ | (/* 2 */ T5); +type A6 = /* 0 */ /* 1 */ | /* 2 */ T6; +type A7 = /* 0 */ | /* 1 */ T7; +type A8 /* = */ /* 1:before */ = /* 2 */ | /* 3 */ T7; diff --git a/tests/format/typescript/union/single-type/single-type-2.ts b/tests/format/typescript/union/single-type/single-type-2.ts new file mode 100644 index 000000000..3ce43b117 --- /dev/null +++ b/tests/format/typescript/union/single-type/single-type-2.ts @@ -0,0 +1,16 @@ +// https://github.com/oxc-project/oxc/pull/21915 +export type myType = | // Comment + "A"; + +// Block comment same-line after pipe +type BlockComment = | /* block */ + "B"; + +// Same-line comment then own-line comment +type Mixed = | // first + // second + "C"; + +// Long line comment that exceeds printWidth on the `=` line +type LongType = | // This is a really long comment that might exceed the print width limit + "A";