Repository navigation
Fix declaration emit renaming value references to shadowed type parameters - #64951
Open
Mariana Castro (maricastroc) wants to merge 4 commits into
Open
Mariana Castro (maricastroc) wants to merge 4 commits into
Mariana Castro (maricastroc) wants to merge 4 commits into
Conversation
…eters A type parameter and a parameter with the same name share one symbol. When reusing nodes, only treat that symbol as a type parameter if the reference is in a type parameter meaning, so predicate targets and `typeof` operands keep the parameter's name and value references go through the regular accessibility check.
…type-parameter-value-references
…n emit tests Add plain and captured assertion predicates and a computed property name whose expression refers to a parameter sharing its name with a shadowed type parameter.
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The narrowly scoped checks preserve value references while retaining type-parameter renaming, and the regression baselines cover the reported failure modes.
No open issues 🎉
What changed in this PR
Fixes #64706 in the native TypeScript compiler by preserving value-reference names when declaration emit renames shadowed type parameters.
Changes:
- Makes identifier rewriting and accessibility checks respect whether a reference uses the type or value meaning.
- Adds regression coverage for predicates, assertions, type queries, computed properties, and parameter-name collisions.
- Records expected declaration output, types, and symbol bindings.
| File | Description |
|---|---|
tsc/internal/checker/nodecopy.go |
Restricts type-parameter renaming to references with the appropriate meaning. |
tsc/testdata/tests/cases/compiler/declarationEmitShadowedTypeParameterSharesParameterName.ts |
Adds regression cases for shared type/value names. |
tsc/testdata/baselines/reference/compiler/declarationEmitShadowedTypeParameterSharesParameterName.types |
Records expected types with preserved value references. |
tsc/testdata/baselines/reference/compiler/declarationEmitShadowedTypeParameterSharesParameterName.symbols |
Records symbol bindings for the regression cases. |
tsc/testdata/baselines/reference/compiler/declarationEmitShadowedTypeParameterSharesParameterName.js |
Records JavaScript and corrected declaration output. |
Review effort: Balanced
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.
Fixes #64706
Problem
A type parameter and a parameter with the same name (
<value>(value: value)) share one symbol. When declaration emit reuses existing type nodes and renames a shadowed inner type parameter (for example tovalue_1), the identifier rewriter innodecopy.goonly checked whether the symbol hadTypeParameterflags. So references that need the value meaning were renamed too:value is ...,asserts value,asserts value is ...)typeof valueandtypeof value.member{ [value]: number })This produced declarations that don't compile (TS1225, TS2693), or, when another parameter was already named
value_1, declarations that compile but refer to the wrong parameter.Fix
attachSymbolToLeftmostIdentifiernow receives the meaning of the reference and only usestypeParameterToNamewhen the symbol is a type parameter in that meaning. The type parameter accessibility shortcut intrackExistingEntityNameuses the same check, so value references to the shared symbol go through the normal accessibility check.Before:
After:
Tests
declarationEmitShadowedTypeParameterSharesParameterName.tscovers type predicates, both assertion forms,typeofin return and parameter types, qualifiedtypeof, computed property names, the cases where another parameter is already namedvalue_1, nested functions, arrow functions, object methods, and a localtypeofthat refers to a different symbol. Thanks Jason Kuhrt (@jasonkuhrt) for the extra cases in the issue.I also checked the emitted declarations with a consumer (
skipLibCheck: false): it type-checks, and the predicates, assertions andtypeofreturn types act on the first parameter, as in the source.npx hereby validatepasses.This PR was prepared with AI assistance (Claude Code).
🤖 Generated with Claude Code