Skip to content

fix(64974): fix contextual typing for destructured parameter defaults - #64978

Open
Oleksandr Tarasiuk (a-tarasyuk) wants to merge 2 commits into
microsoft:mainfrom
a-tarasyuk:fix/64974
Open

Oleksandr Tarasiuk (a-tarasyuk) wants to merge 2 commits into
microsoft:mainfrom
a-tarasyuk:fix/64974

Conversation

@a-tarasyuk

Copy link
Copy Markdown
Contributor

Fixes #64974

Copilot AI balanced review requested due to automatic review settings October 27, 2026 10:08
@typescript-automation typescript-automation Bot added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label Oct 27, 2026
@github-project-automation github-project-automation Bot moved this to Not started in PR Backlog Oct 27, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

Static review identified no blocking issues in the focused fix and regression baselines; automated validation was not run.

No open issues 🎉

What changed in this PR

Fixes #64974 by preserving contextual types for destructured parameter defaults, preventing incorrect TS7031 errors.

Changes:

  • Skip object-literal padding when the root parameter has a contextual type.
  • Add regression cases for optional parameters, nested destructuring, arrays, index signatures, and generic callbacks.
  • Update type, symbol, and diagnostic baselines.
File Description
tsc/​testdata/​tests/​cases/​compiler/​objectBindingPatternDefaultMissingElements.ts Adds contextual-typing regression cases.
tsc/​testdata/​baselines/​reference/​compiler/​objectBindingPatternDefaultMissingElements.types Records expected inferred types.
tsc/​testdata/​baselines/​reference/​compiler/​objectBindingPatternDefaultMissingElements.symbols Records symbols for the added cases.
tsc/​testdata/​baselines/​reference/​compiler/​objectBindingPatternDefaultMissingElements.errors.txt Records expected diagnostics without spurious implicit-any errors.
tsc/​internal/​checker/​checker.go Guards object-literal padding to preserve contextual typing.

Review effort: Balanced

@timurzvural

Copy link
Copy Markdown

Opened #65016 as an alternative that also covers #65011.

Same contextual-type guard for object padding; additionally guards array padding and adds JSDoc @returns / cast / annotated .ts cases from #65011 on top of the #64974 scenarios.

@nrjdalal

Copy link
Copy Markdown

One more shape for the test file, from a codebase that hit this on 7.1: a pattern where some binding elements have their own defaults. Only the elements without a default are flagged; the ones with a default keep their type.

// tsconfig: { "compilerOptions": { "strict": true, "noEmit": true, "target": "esnext", "module": "esnext", "types": [] } }
type Run = (argv: string[], options?: { cwd?: string; timeout?: number }) => void

export const run: Run = (argv, { cwd, timeout = 1 } = {}) => {
  const n: number = timeout
  console.log(argv, cwd, n)
}
Version Result
7.0.2 no errors
7.1.0-beta (4,34): error TS7031: Binding element 'cwd' implicitly has an 'any' type.
7.1.0-dev.20261029.1 same

f1 here covers the plain ({ a, b } = {}) form. A case like ({ a, b = 1 } = {}) would pin the mixed form too. With this PR's guard, cwd should read string | undefined and timeout should read number, as on 7.0.2.

@timurzvural

Copy link
Copy Markdown

Good catch — that mixed form is the same regression.

On 7.1, padding invents any for missing properties on the = {} default and overrides the contextual parameter type, so cwd becomes implicit any (TS7031) while timeout = 1 keeps a usable type from its own initializer. With the contextual-type guard (skip padObjectLiteralType when the root parameter already has a contextual type), cwd should be string | undefined and timeout should be number, matching 7.0.2.

I opened #65016 as an alternative that uses the same object-padding guard (and also guards array padding). I will add an explicit ({ cwd, timeout = 1 } = {}) / ({ a, b = 1 } = {}) case there so the mixed shape is pinned in baselines, not only the plain ({ a, b } = {}) form from #64974.

This branch has not been deployed

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

Labels

For Uncommitted Bug PR for untriaged, rejected, closed or missing bug

Projects

Status: Not started

Development

Successfully merging this pull request may close these issues.

7.1: destructured parameter with a = {} default loses its contextual type (TS7031)

4 participants