Detect self-referencing mapped type constraints - #64538
Open
Naji Ullah (Naji-Ullah) wants to merge 2 commits into
Open
Naji Ullah (Naji-Ullah) wants to merge 2 commits into
Naji Ullah (Naji-Ullah) wants to merge 2 commits into
Conversation
Copilot started reviewing on behalf of
Naji Ullah (Naji-Ullah)
September 29, 2026 17:20
View session
Contributor
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The implementation is narrowly scoped and its diagnostic, recovery, instantiation, shadowing, and declaration-emit behavior are covered by regression baselines.
Review effort: Balanced
Findings: None
What changed in this PR
Adds circular-constraint detection for self-referencing mapped type parameters and prevents them from leaking into declaration output.
Changes:
- Detect mapped type parameters referenced within their own constraints.
- Substitute the error type after reporting circularity.
- Add regression tests and compiler baselines for errors, types, symbols, and declaration emit.
| File | Description |
|---|---|
tsc/internal/checker/checker.go |
Implements self-reference detection and error recovery. |
tsc/testdata/tests/cases/compiler/circularMappedTypeConstraint2.ts |
Adds positive and negative regression cases. |
tsc/testdata/baselines/reference/compiler/circularMappedTypeConstraint2.errors.txt |
Records expected diagnostics. |
tsc/testdata/baselines/reference/compiler/circularMappedTypeConstraint2.js |
Verifies JavaScript and declaration output. |
tsc/testdata/baselines/reference/compiler/circularMappedTypeConstraint2.types |
Records inferred types. |
tsc/testdata/baselines/reference/compiler/circularMappedTypeConstraint2.symbols |
Records symbol resolution. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
Author
|
@microsoft-github-policy-service agree |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


With this PR we report a circularity error when the type parameter of a mapped type is referenced in its own constraint. Previously such circularities were detected only when base constraint resolution happened to revisit the type parameter (as in
{ [P in P]: X }), but not when the reference occurred in a position whose base constraint doesn't depend on it, such askeyof P. In the exampleno error was reported, and
Pescaped from the mapped type into the generated declaration file:We now report
on
keyof P, the same error we already report for{ [P in P]: X }, and we use the error type as the constraint soPno longer escapes (the declaration above becomesgetTest(): any). The check happens where the declared constraint of a mapped type parameter is resolved, so it also covers instantiations of generic mapped types. It applies only to mapped types, so ordinary type parameters such asT extends keyof Tare unaffected. Any reference to the type parameter within its own constraint is considered circular, including one that doesn't affect the resulting keys, such as{ [P in keyof { a: P }]: X }.The new test
circularMappedTypeConstraint2.tscovers the example above, variants such askeyof P | "x",Extract<keyof P, string>,keyof Cond<P>, and a generic mapped type and its instantiation, as well as cases that must remain error-free (T extends keyof T, a shadowed innerP, and anasclause referencingP). No existing baselines are affected.AI disclosure: I used an AI coding assistant (Claude Code) while investigating and writing this fix. I've reviewed the change and the tests, I understand them, and I'll be handling review feedback myself.
Fixes #62176.