Skip to content

fix(es/parser): emit TS2371 for object defaults in declare signatures - #12095

Open
Felix-Ayush (Ayush7614) wants to merge 4 commits into
swc-project:mainfrom
Ayush7614:fix/ts2371-declare-object-defaults
Open

fix(es/parser): emit TS2371 for object defaults in declare signatures#12095
Felix-Ayush (Ayush7614) wants to merge 4 commits into
swc-project:mainfrom
Ayush7614:fix/ts2371-declare-object-defaults

Conversation

@Ayush7614

@Ayush7614 Felix-Ayush (Ayush7614) commented Jul 31, 2026

Copy link
Copy Markdown

Description:

TypeScript's TS2371 forbids parameter initializers in ambient / declare signatures. SWC already rejected top-level AssignPat defaults (and array defaults like declare function bar([x = 1])), but object shorthand defaults ({ a = 1 }) use AssignPatProp and skipped the InDeclare check. There was also a TODO: Search deeply for assignment pattern on declare function/constructor validation.

This change:

  • emits TS2371 when parsing object shorthand defaults under InDeclare
  • deeply walks declare function / constructor parameter patterns for nested initializers

Verified against tsc and with fixtures under tests/typescript-errors/ts2371/**.

Related issue (if exists):

N/A (direct PR; no existing tracked issue)

Ambient/declare parameter lists already rejected AssignPat defaults, but
object shorthand defaults use AssignPatProp and skipped the InDeclare
check. Emit TS2371 for those defaults and deeply walk declare
function/constructor parameters for nested initializers.
@Ayush7614
Felix-Ayush (Ayush7614) requested review from a team as code owners July 31, 2026 10:11
@changeset-bot

changeset-bot Bot commented Jul 31, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 732b90e

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

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

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c76a9eae77

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Comment on lines +82 to +84
if self.ctx().contains(Context::InDeclare) {
self.emit_err(self.span(start), SyntaxError::TS2371);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Don't report TS2371 for ambient destructuring bindings

This check runs for every object binding pattern parsed under Context::InDeclare, not just function/constructor parameters. For example, declare const { a = 1 }: { a?: number }; reaches this branch while parsing the variable declarator, and TypeScript accepts that ambient destructuring binding, but SWC will now emit the parameter-only TS2371 diagnostic. Narrow the eager check to parameter/signature parsing (or rely on the post-parse parameter traversal) so declare variable bindings are not rejected.

Useful? React with 👍 / 👎.

@codspeed-hq

codspeed-hq Bot commented Jul 31, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 200 untouched benchmarks
⏩ 61 skipped benchmarks1


Comparing Ayush7614:fix/ts2371-declare-object-defaults (732b90e) with main (5b758ed)

Open in CodSpeed

Footnotes

  1. 61 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Object shorthand defaults under InDeclare also appear in ambient
variable bindings such as `declare const { a = 1 }`, which TypeScript
accepts. Drop the eager object-pattern check and limit binding-element
TS2371 to parameter lists; declare signatures still use the post-parse
walk.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a15012a7d8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

if self.ctx().contains(Context::InDeclare) {
// Only reject defaults in declare *parameter* lists. Ambient
// destructuring bindings such as `declare const { a: b = 1 }` are valid.
if self.ctx().contains(Context::InDeclare) && self.ctx().contains(Context::InParameters)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve TS2371 in .d.ts signature parameters

This guard fixes ambient variable destructuring, but it also disables the existing TS2371 check for .d.ts function/type signatures parsed through parse_ts_binding_list_for_signature, because that path has Context::InDeclare set but never enters Context::InParameters. As a result, inputs like type T = ({ a: b = 1 }: { a?: number }) => void; are now accepted by SWC even though tsc --noEmit reports TS2371, and the new recursive checker only runs for function/constructor nodes with body.is_none(), not TsFnParam signatures.

Useful? React with 👍 / 👎.

pub(crate) fn emit_ts2371_for_param_initializers(&mut self, pat: &Pat) {
match pat {
Pat::Assign(a) => {
self.emit_err(a.span(), SyntaxError::TS2371);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid re-emitting TS2371 for parsed declare defaults

For declare function/method signatures parsed under Context::InParameters, nested Pat::Assign defaults have already reported TS2371 from parse_binding_element before this post-parse walk runs. This line reports the same span a second time for cases such as declare function f([x = 1]): void; or declare function f({ a: b = 1 }): void;, so consumers and the newly added stderr fixtures will see duplicate TS2371 diagnostics unless the walker skips already-checked assign patterns in that context or the eager check is centralized here.

Useful? React with 👍 / 👎.

Drop eager InDeclare emits that double-fired with the post-list walker
for declare functions. Recover AssignPat in signature bindings as
TS2371 and walk nested object/array defaults in type/call/method
signatures.
Drop eager InDeclare emits that double-fired with the post-list walker
for declare functions. Recover AssignPat in signature bindings as
TS2371 and walk nested object/array defaults in type/call/method
signatures.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 732b90e090

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

})
}

#[test]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Move duplicate TS2371 coverage into fixtures

This new #[test] adds parser coverage outside the fixture suites even though this commit already adds tests/typescript-errors/ts2371/mixed, whose stderr snapshot would catch duplicate TS2371 diagnostics. Keeping the ad-hoc inline test bypasses the parser fixture workflow and violates the repo's fixture-test convention; please move the duplicate-diagnostic assertion into the fixture suite or rely on the existing stderr fixture.

AGENTS.md reference: AGENTS.md:L52-L55

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant