Fix Union type alignment (#18165)

This commit is contained in:
fisker Cheung authored and GitHub committed 2025-10-31 08:31:54 +08:00
1 parent 528638031a
commit 1a3d443797
10 files changed
+203 -57

No files matched your search

+1 -1
View File
@@ -11,6 +11,6 @@
// Prettier stable (--parser=flow)
1 /* comment */ as const;
// Prettier main (--parser=typescript)
// Prettier main (Same output for `--parser=typescript` and `--parser=flow`)
1 /* comment */ as const;
```
+25
View File
@@ -0,0 +1,25 @@
#### Fix miss aligned union type (#18165 by @fisker)
<!-- prettier-ignore -->
```tsx
// Input
interface I {
elements: // comment
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression]
}
// Prettier stable
interface I {
elements: // comment
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression];
}
// Prettier main
interface I {
elements: // comment
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression];
}
```
+21 -10
View File
@@ -152,17 +152,28 @@ function canAttachComment(node, ancestors) {
*/
function willPrintOwnComments(path) {
const { node, parent } = path;
if (path.key === "types" && isUnionType(parent)) {
return true;
}
if (hasNodeIgnoreComment(node)) {
return false;
}
if (isJsxElement(node) || isUnionType(node)) {
return true;
}
if (!parent) {
return false;
}
return (
(isJsxElement(node) ||
(parent &&
(parent.type === "JSXSpreadAttribute" ||
parent.type === "JSXSpreadChild" ||
isUnionType(parent) ||
parent.type === "MatchOrPattern" ||
((parent.type === "ClassDeclaration" ||
parent.type === "ClassExpression") &&
parent.superClass === node)))) &&
(!hasNodeIgnoreComment(node) || isUnionType(parent))
parent.type === "JSXSpreadAttribute" ||
parent.type === "JSXSpreadChild" ||
parent.type === "MatchOrPattern" ||
(path.key === "superClass" &&
(parent.type === "ClassDeclaration" || parent.type === "ClassExpression"))
);
}
+21 -10
View File
@@ -7,7 +7,10 @@ import {
line,
softline,
} from "../../document/builders.js";
import { printComments } from "../../main/comments/print.js";
import {
printComments,
printCommentsSeparately,
} from "../../main/comments/print.js";
import { hasSameLocStart } from "../loc.js";
import pathNeedsParens from "../needs-parens.js";
import {
@@ -230,25 +233,30 @@ function printUnionType(path, options, print) {
if (!shouldHug) {
printedType = align(2, printedType);
}
return printComments(path, printedType, options);
}, "types");
const { leading, trailing } = printCommentsSeparately(path, options);
if (shouldHug) {
return join(" | ", printed);
return [leading, join(" | ", printed), trailing];
}
const shouldAddStartLine =
shouldIndent && !hasLeadingOwnLineComment(options.originalText, node);
const code = [
const mainParts = [
ifBreak([shouldAddStartLine ? line : "", "| "]),
join([line, "| "], printed),
];
if (pathNeedsParens(path, options)) {
return group([indent(code), softline]);
return [leading, group([indent(mainParts), softline]), trailing];
}
const parts = [leading, group(mainParts)];
if (parent.type === "TupleTypeAnnotation" || parent.type === "TSTupleType") {
const elementTypes =
parent[
@@ -259,15 +267,18 @@ function printUnionType(path, options, print) {
];
if (elementTypes.length > 1) {
return group([
indent([ifBreak(["(", softline]), code]),
softline,
ifBreak(")"),
]);
return [
group([
indent([ifBreak(["(", softline]), parts]),
softline,
ifBreak(")"),
]),
trailing,
];
}
}
return group(shouldIndent ? indent(code) : code);
return [group(shouldIndent ? indent(parts) : parts), trailing];
}
/*
@@ -14,7 +14,7 @@ const myValue = (callcallcallcallcallcall(87689769876876897698768768976987687689
const myValue = (callcallcallcallcallcall(
87689769876876897698768768976987687689769876,
): // Comment
| one
| one
| two
| thre
| jdkxhflksjdhfglkjsdhfglkjhsdkfljghskdjhfgkljshdfgkjhsdkljfhgkljshdfgjdfklgjhklj);
@@ -49,14 +49,14 @@ type a= {
[A in B]: C | D
}
type a= {
type b= {
[
// prettier-ignore
A in B
]: C | D
}
type a= {
type c= {
[
A in
// prettier-ignore
@@ -64,20 +64,20 @@ type a= {
]: C | D
}
type a= {
type d= {
[A in B]:
// prettier-ignore
C | D
}
type a= {
type e= {
[
/* prettier-ignore */
A in B
]: C | D
}
type a= {
type f= {
[
A in
/* prettier-ignore */
@@ -85,30 +85,30 @@ type a= {
]: C | D
}
type a= {
type g= {
[A in B]:
/* prettier-ignore */
C | D
}
type a= {
type h= {
/* prettier-ignore */ [A in B]: C | D
}
type a= {
type i= {
[/* prettier-ignore */ A in B ]: C | D
}
type a= {
type j= {
[A in /* prettier-ignore */ B]: C | D
}
type a= {
type k= {
[A in B]: /* prettier-ignore */ C | D
}
type a= {
type l= {
/* prettier-ignore */
[A in B]: C | D
}
@@ -119,57 +119,57 @@ type a = {
[A in B]: C | D
};
type a = {
type b = {
[
// prettier-ignore
A in B
]: C | D
};
type a = {
type c = {
[A in // prettier-ignore
B]: C | D;
};
type a = {
type d = {
[A in B]: // prettier-ignore
C | D;
C | D;
};
type a = {
type e = {
[
/* prettier-ignore */
A in B
]: C | D
};
type a = {
type f = {
[A in /* prettier-ignore */
B]: C | D;
};
type a = {
type g = {
[A in B]: /* prettier-ignore */
C | D;
C | D;
};
type a = {
type h = {
/* prettier-ignore */ [A in B]: C | D
};
type a = {
type i = {
[/* prettier-ignore */ A in B ]: C | D
};
type a = {
type j = {
[A in /* prettier-ignore */ B]: C | D;
};
type a = {
type k = {
[A in B]: /* prettier-ignore */ C | D;
};
type a = {
type l = {
/* prettier-ignore */
[A in B]: C | D
};
@@ -3,14 +3,14 @@ type a= {
[A in B]: C | D
}
type a= {
type b= {
[
// prettier-ignore
A in B
]: C | D
}
type a= {
type c= {
[
A in
// prettier-ignore
@@ -18,20 +18,20 @@ type a= {
]: C | D
}
type a= {
type d= {
[A in B]:
// prettier-ignore
C | D
}
type a= {
type e= {
[
/* prettier-ignore */
A in B
]: C | D
}
type a= {
type f= {
[
A in
/* prettier-ignore */
@@ -39,30 +39,30 @@ type a= {
]: C | D
}
type a= {
type g= {
[A in B]:
/* prettier-ignore */
C | D
}
type a= {
type h= {
/* prettier-ignore */ [A in B]: C | D
}
type a= {
type i= {
[/* prettier-ignore */ A in B ]: C | D
}
type a= {
type j= {
[A in /* prettier-ignore */ B]: C | D
}
type a= {
type k= {
[A in B]: /* prettier-ignore */ C | D
}
type a= {
type l= {
/* prettier-ignore */
[A in B]: C | D
}
@@ -0,0 +1,29 @@
export interface DirectiveArgumentNode extends ArrayExpression {
elements: // dir, exp, arg, modifiers
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression]
}
export class DirectiveArgumentNode2 extends ArrayExpression {
elements: // dir, exp, arg, modifiers
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression]
= 1
}
type A = // dir, exp, arg, modifiers
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression]
const elements: // dir, exp, arg, modifiers
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression]
= 1
@@ -0,0 +1,69 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`18106.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]
}
export class DirectiveArgumentNode2 extends ArrayExpression {
elements: // dir, exp, arg, modifiers
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression]
= 1
}
type A = // dir, exp, arg, modifiers
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression]
const elements: // dir, exp, arg, modifiers
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression]
= 1
=====================================output=====================================
export interface DirectiveArgumentNode extends ArrayExpression {
elements: // dir, exp, arg, modifiers
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression];
}
export class DirectiveArgumentNode2 extends ArrayExpression {
elements: // dir, exp, arg, modifiers
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression] = 1;
}
type A = // dir, exp, arg, modifiers
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression];
const elements: // dir, exp, arg, modifiers
| [string]
| [string, ExpressionNode]
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression] = 1;
================================================================================
`;
@@ -0,0 +1 @@
runFormatTest(import.meta, ["typescript", "flow"]);