Repository navigation
Do not pad binding elements that the parameter's type already types - #64671
dev (Konan69) wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Nested contextual bindings can remain implicitly any while their diagnostic is suppressed.
1 open finding
What changed in this PR
Prevents false TS7031 diagnostics for typed binding elements with default object literals.
Changes:
- Gates implicit-any reporting on root parameter typing.
- Adds contextual and annotated regression cases with baselines.
| File | Description |
|---|---|
tsc/internal/checker/checker.go |
Adjusts implicit-any reporting. |
tsc/testdata/tests/cases/compiler/objectBindingPatternDefaultMissingElements.ts |
Adds regression cases. |
tsc/testdata/baselines/reference/compiler/objectBindingPatternDefaultMissingElements.types |
Updates type baseline. |
tsc/testdata/baselines/reference/compiler/objectBindingPatternDefaultMissingElements.symbols |
Updates symbol baseline. |
tsc/testdata/baselines/reference/compiler/objectBindingPatternDefaultMissingElements.errors.txt |
Updates diagnostic baseline. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
| // gets its binding element types from the annotation and a contextually typed one from the | ||
| // contextual signature, so the implicit any error would contradict the element's own type. | ||
| root := ast.GetRootDeclaration(pattern.Parent) | ||
| reportErrors := !(ast.IsParameterDeclaration(root) && (root.Type() != nil || c.getContextuallyTypedParameterType(root) != nil)) |
There was a problem hiding this comment.
Good catch, that was right. The new commit resolves each element through the annotation or contextual type and skips the padding for it, so the nested case is boolean | undefined again, and the test now asserts the types.
padObjectLiteralType pads every binding element missing from a parameter's
default object literal with the element's own type, which is implicitly any
when the element has no initializer. For an annotated or contextually typed
parameter that replaces the type the annotation or the contextual signature
gives the element, and reports TS7031 on an element that has a type:
type Options = (options?: { recursive?: boolean }) => void;
const f: Options = ({ recursive } = {}) => {};
// ~~~~~~~~~ TS7031, but recursive is boolean | undefined
Resolve the type the pattern destructures from the annotation or the
contextual signature, through nested patterns, and leave out of the padding
each element that type has. Elements it does not have are padded and reported
as before.
c435387 to
42826db
Compare
|
dev (@Konan69) please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.
Contributor License AgreementContribution License AgreementThis Contribution License Agreement (“Agreement”) is agreed to by the party signing below (“You”),
|

Fixes #64431
#64043 made
padObjectLiteralTypepad every binding element missing from a parameter's default object literal, using the element's own type, which is implicitlyanywhen the element has no initializer. For an annotated or contextually typed parameter this reports TS7031 on an element that already has a type, and for nested patterns it also replaces that type withany:Change
padObjectLiteralTypenow resolves the type the pattern destructures from the parameter's annotation or its contextual signature, walking nested object patterns by property name, and does not pad an element that this type has. Elements the type does not have are padded and reported exactly as before, so a parameter with no type anywhere keeps its TS7031, which is what #64043 intended. The lookup (getDeclaredTypeOfParameterBindingPattern) never consults an initializer.The first version of this PR only suppressed the diagnostic. The review pointed out that a nested contextually typed element then stayed
anysilently; that was right, and this version fixes the type as well as the diagnostic.Relation to #64440
I saw the draft in #64440 after starting this. It skips the padding only when every element of the pattern resolves through the contextual type. This PR decides per element, which differs in one case I could find:
knownunknownnumber | undefinedOn every other case below the two give the same result. Please close this if you prefer to finish #64440.
Tests
Added to
objectBindingPatternDefaultMissingElements, each with an assignment tostringso the errors baseline shows the element's type:= {}default in an annotated parameter (regression from #64043) #64431.go test ./internal/testrunner -run TestLocalandgo test ./internal/checker/...pass; the only baselines that change are that test's, and its 5 intended TS7031 errors are unchanged. I have not runhereby lintor the submodule tests.How we found it
We were evaluating type checkers and build tooling for a large TypeScript monorepo (an AI product: 17 projects, Effect 4). A checker that tracks current
mainreported 3 lines that7.0.2does not, all this error, on an object literal implementing an SDK interface (mkdir: (path, { recursive } = {}) => ...). Bisecting the nightlies gave7.1.0-dev.20260922.1as the last good and7.1.0-dev.20260923.1as the first bad;6.0.3and7.0.2accept the code.For reference, the whole-repo check on that monorepo, cold, 17 projects with declarations, on a 16-core machine:
tsc7.0.2,--checkers 1tsc7.0.2, default checkersAI disclosure
This patch was written with an AI coding tool. I have read it, I understand it, and I will handle the review myself.