Skip to content

Commit 120197e

Browse files
committed
fix: surround template literal type expressions with newlines on multi-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
1 parent f7dd1f3 commit 120197e

2 files changed

Lines changed: 24 additions & 0 deletions

File tree

src/generation/generate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3279,6 +3279,7 @@ fn gen_template_literal<'a>(quasis: Vec<Node<'a>>, exprs: Vec<Node<'a>>, context
32793279
Node::OptChainExpr(expr) => get_possible_surround_newlines(expr.base.as_node()),
32803280
Node::CondExpr(_) => true,
32813281
Node::BinExpr(_) => true,
3282+
Node::TsUnionType(_) | Node::TsIntersectionType(_) => true,
32823283
Node::MemberExpr(expr) => !keep_member_expr_on_one_line(expr),
32833284
Node::CallExpr(expr) => !keep_call_expr_on_one_line(expr.into()),
32843285
Node::OptCall(expr) => !keep_call_expr_on_one_line(expr.into()),
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
1+
~~ lineWidth: 80, indentWidth: 2 ~~
12
== should format a template literal type ==
23
type Test<T> = `${string & keyof T}Changed`;
34

45
[expect]
56
type Test<T> = `${string & keyof T}Changed`;
7+
8+
== should keep union template literal type expression on one line when it fits ==
9+
type Foo = `${typeof X | typeof Y}__${typeof Z | typeof W}`;
10+
11+
[expect]
12+
type Foo = `${typeof X | typeof Y}__${typeof Z | typeof W}`;
13+
14+
== should surround union template literal type expression with newlines when too long ==
15+
export type SortSelector = `${typeof Descending | typeof Ascending}${SortItems}`;
16+
17+
[expect]
18+
export type SortSelector = `${
19+
typeof Descending | typeof Ascending
20+
}${SortItems}`;
21+
22+
== should surround intersection template literal type expression with newlines when too long ==
23+
export type IntersectionTpl = `${typeof Descending & typeof Ascending}${SortItems}`;
24+
25+
[expect]
26+
export type IntersectionTpl = `${
27+
typeof Descending & typeof Ascending
28+
}${SortItems}`;

0 commit comments

Comments
 (0)