Skip to content

Inconsistent comment placement in nested unions vs unions in intersections #18778

@Dunqing

Description

@Dunqing

Prettier 3.8.1
Playground link

--parser typescript

Input:

type UnionInIntersection = (
  | "thing1" // Comment1
  | "thing2" // Comment2
) & Bar; // Final comment2

type NestedUnion = (
  | "thing1" // Comment1
  | "thing2" // Comment2
) | Bar; // Final comment2


type UnionInIntersection2 =
  (
  	A | B // comment 1
  ) & (
  	// comment2
    A | B
  )

type NestedUnion2 =
  (
  	A | B // comment 1
  ) | (
  	// comment2
    A | B
  )

Output:

type UnionInIntersection = (
  | "thing1" // Comment1
  | "thing2" // Comment2
) &
  Bar; // Final comment2

type NestedUnion =
  | (
      | "thing1" // Comment1
      | "thing2"
    ) // Comment2
  | Bar; // Final comment2

type UnionInIntersection2 = (
  | A
  | B // comment 1
) &
  // comment2
  (A | B);

type NestedUnion2 =
  | (A | B) // comment 1
  // comment2
  | (A | B);

Expected output:

type UnionInIntersection = (
  | "thing1" // Comment1
  | "thing2" // Comment2
) &
  Bar; // Final comment2

type NestedUnion = (
  | "thing1" // Comment1
  | "thing2" // Comment2
) |
  Bar; // Final comment2

type UnionInIntersection2 = (
  | A
  | B // comment 1
) &
  // comment2
  (A | B);

type NestedUnion2 = (
  | A
  | B // comment 1
) |
  // comment2
  (A | B);

Why?

The current output shows inconsistent comment handling between union-in-intersection and union-in-union cases:

  1. UnionInIntersection - Comments stay on their original lines:

    type UnionInIntersection = (
      | "thing1" // Comment1
      | "thing2" // Comment2
    ) & Bar;
  2. NestedUnion - Comments get repositioned, with // Comment2 moved outside the parentheses:

    type NestedUnion =
      | (
          | "thing1" // Comment1
          | "thing2"
        ) // Comment2
      | Bar;

This inconsistency is problematic because:

  • Comment semantics change: // Comment2 was originally associated with "thing2", but after formatting it appears to comment on the entire parenthesized group
  • Developer intent is lost: Comments are placed deliberately; reformatting should preserve their associations

The expected output keeps the parenthesized union structure intact with comments in their original positions, matching the behavior of UnionInIntersection.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:union typeslang:typescriptIssues affecting TypeScript-specific constructs (not general JS issues)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions