Skip to content

formatter: Arrow function body breaks after => when JSDoc type cast is in body #20180

@Dunqing

Description

@Dunqing

Input

Found in sveltejs/svelte repo.

Files: packages/svelte/src/compiler/legacy.js (20+ instances), packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js, packages/svelte/src/compiler/phases/3-transform/client/visitors/Program.js, packages/svelte/src/compiler/phases/3-transform/server/visitors/Program.js, packages/svelte/src/compiler/phases/3-transform/shared/transform-async.js

Minimal reproduction:

// Example 1: .map() callback
const result = items.map(
  (child) => /** @type {SomeType} */ (visit(child))
);

// Example 2: function argument
const body = transform_body(
  state.analysis.instance_body,
  b.id('$.run'),
  (node) => /** @type {Node} */ (context.visit(node))
);

Config

{
  "useTabs": true,
  "singleQuote": true,
  "trailingComma": "none",
  "printWidth": 100
}

Oxfmt output

// Example 1
const result = items.map((child) =>
	/** @type {SomeType} */ (visit(child))
);

// Example 2
const body = transform_body(state.analysis.instance_body, b.id('$.run'), (node) =>
	/** @type {Node} */ (context.visit(node))
);

Prettier output

Prettier version: 3.8.1

// Example 1
const result = items.map(
	(child) => /** @type {SomeType} */ (visit(child))
);

// Example 2
const body = transform_body(
	state.analysis.instance_body,
	b.id('$.run'),
	(node) => /** @type {Node} */ (context.visit(node))
);

Additional notes

When an arrow function body starts with a JSDoc inline type cast (/** @type {X} */), Prettier breaks after the opening parenthesis and keeps the entire arrow expression on one line, while Oxfmt breaks after => and puts the JSDoc type cast + body on the next line.

This pattern occurs 20+ times in legacy.js alone (all with the same .map((child) => /** @type {X} */ (visit(child))) pattern), plus several other files. It's the most frequent diff in the Svelte repo.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions