Skip to content

fix: don't treat JSDoc type casts on param defaults and named function ids as casts - #182

Open
koding88 wants to merge 2 commits into
sveltejs:mainfrom
koding88:fix/jsdoc-cast-param-bindings
Open

fix: don't treat JSDoc type casts on param defaults and named function ids as casts#182
koding88 wants to merge 2 commits into
sveltejs:mainfrom
koding88:fix/jsdoc-cast-param-bindings

Conversation

@koding88

Copy link
Copy Markdown

Fixes #181.

The binding-position tracking introduced in #167 marks the parameter nodes themselves, but a parameter with a default value is an AssignmentPattern — the binding is its left identifier, which was never marked. A /** @type {…} */ comment re-anchored there (svelte re-anchors template comments onto freshly generated nodes with synthetic locs) is still treated as a cast and the binding target gets wrapped, producing output that fails to parse:

const row_template = ($$anchor, /** @type {any} */ (row) = $.noop) => {
``
A named function's `id` has the same gap: the flush can wrap it into `function /** @type {any} */ (h)(…)`.

This marks `AssignmentPattern.left` alongside its parent pattern (via a `track_param_bindings` helper used at every param-tracking call site) and tracks `FunctionDeclaration`/`FunctionExpression` ids as binding positions.

New regression test: `test/comment-jsdoc-type-cast-bindings.test.js` (asserts the output stays valid JS), plus a sample under `test/samples/comment-jsdoc-type-cast-param-default/`. All 297 tests pass, `pnpm check` and `pnpm lint` are clean.

…as casts

The binding-position tracking from sveltejs#167 covers the param nodes themselves,
but two binding shapes were still reachable by the JSDoc cast heuristic:

1. A parameter with a default value is an AssignmentPattern; the binding is
   its left identifier, which was never marked — a comment re-anchored there
   (as svelte does for snippet params) got wrapped: '(row) = $.noop', which
   fails to parse.
2. A named function's id was never marked, allowing 'function /** @type */
   (h)(...)' output.

Track AssignmentPattern.left next to its parent pattern, and track
FunctionDeclaration/FunctionExpression ids as binding positions.
Copilot AI lite review requested due to automatic review settings August 27, 2026 08:32
@changeset-bot

changeset-bot Bot commented Aug 27, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 15f4285

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
esrap Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-svelte-dev

Copy link
Copy Markdown

Install the latest version of esrap from 15f4285:

pnpm add https://pkg.svelte.dev/esrap/c/15f428543186055d0bd8805cefe18cf3664d6634

Open in pkg.svelte.dev: https://pkg.svelte.dev/repos/esrap/pr/182

Note

This PR is from a fork. A maintainer must approve approve each commit before it can be built and installed.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the TypeScript printer’s “binding-position” tracking so that JSDoc @type comments re-anchored onto function-parameter binding targets (including defaulted params) and named function identifiers are not misdetected as type casts (which would otherwise cause invalid parentheses wrapping and broken output JS).

Changes:

  • Add track_param_bindings to mark AssignmentPattern.left as a binding position (fixing default-parameter cases).
  • Track FunctionDeclaration / FunctionExpression id nodes as binding positions (fixing named-function id wrapping).
  • Add a regression test and a sample fixture to ensure printed output stays valid JavaScript.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/languages/ts/index.js Introduces track_param_bindings and expands binding tracking to prevent JSDoc @type casts from wrapping binding targets.
test/comment-jsdoc-type-cast-bindings.test.js Regression test ensuring re-anchored JSDoc @type on default params does not introduce invalid (row) = ... syntax and output parses.
test/samples/comment-jsdoc-type-cast-param-default/input.js Adds a fixture that includes parameter defaults and a genuine JSDoc cast expression.
test/samples/comment-jsdoc-type-cast-param-default/expected.js Expected printed output for the new sample.
test/samples/comment-jsdoc-type-cast-param-default/expected.js.map Expected sourcemap output for the new sample.
.changeset/fix-jsdoc-cast-param-bindings.md Patch changeset describing the fix for parameter defaults and named function ids.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/languages/ts/index.js
Comment on lines +115 to +119
for (const param of params) {
if (/** @type {any} */ (param)?.type === 'AssignmentPattern') {
track_binding(/** @type {any} */ (param).left);
}
}
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.

JSDoc type-cast parentheses applied to function parameters produce invalid output ((row) = fallback) — regression in 2.3.3

2 participants