Skip to content

fix: surround template literal type unions with newlines when too long#794

Open
divybot wants to merge 1 commit into
dprint:mainfrom
divybot:fix-template-literal-type-union-surround
Open

fix: surround template literal type unions with newlines when too long#794
divybot wants to merge 1 commit into
dprint:mainfrom
divybot:fix-template-literal-type-union-surround

Conversation

@divybot

@divybot divybot commented May 28, 2026

Copy link
Copy Markdown

Note

This PR was authored with the help of an AI coding assistant (Claude Code) running as a bot on behalf of @littledivy. The diagnosis, fix, and tests were reviewed before opening.

Summary

When a template literal type contains a TsUnionType or
TsIntersectionType inside a ${...} placeholder, the generator
breaks on the separator (| / &) when the line is too long but
never inserts the surrounding newlines + indent that other
expression-like nodes (BinExpr, CondExpr, etc.) already get.

Reported downstream as denoland/deno#29868.

Before

export type SortSelector = `${typeof Descending | typeof Ascending}${SortItems}`;

formats to

export type SortSelector = `${
  | typeof Descending
  | typeof Ascending}${SortItems}`;

(closing } is stuck on the last union element's line).

After

export type SortSelector = `${
  typeof Descending | typeof Ascending
}${SortItems}`;

Fix

Add TsUnionType and TsIntersectionType to
get_possible_surround_newlines inside gen_template_literal. This
reuses the existing
surround_with_newlines_indented_if_multi_line codepath, so the
union expression stays on one line whenever it fits inside the
indented inner column and otherwise gets a clean indented block.

Test plan

  • New spec cases in tests/specs/types/TplLitType/TplLitType_All.txt
    cover: union short enough to stay inline, union too long for one
    line, intersection too long for one line.

…i-line

When a template literal type's `${...}` placeholder contains an expression
that does not fit on a single line (notably a `TsUnionType` or
`TsIntersectionType`), the generator broke on the separator (`|` / `&`)
without adding the surrounding newlines + indent that `BinExpr`,
`CondExpr`, etc. already trigger. This produced output like

    export type SortSelector = `${
      | typeof Descending
      | typeof Ascending}${SortItems}`;

instead of

    export type SortSelector = `${
      typeof Descending | typeof Ascending
    }${SortItems}`;

Adding `TsUnionType` and `TsIntersectionType` to
`get_possible_surround_newlines` reuses the existing
`surround_with_newlines_indented_if_multi_line` codepath, so the union
expression stays on one line whenever it fits inside the indented inner
column and otherwise gets a clean indented block — matching how
`BinExpr` is already handled.

Closes denoland/deno#29868
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant