Repository navigation
erase decorated abstract properties under experimentalDecorators with define semantics - #64982
Open
Harsh Vardhan Chauhan (1-DARK) wants to merge 2 commits into
Conversation
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
A decorated abstract computed property with a unique-symbol key can emit an undeclared temporary because its rebuilt node lacks NodeFlagsAmbient, causing a ReferenceError during class evaluation.
1 open issue
What changed in this PR
Addresses #64980 by erasing decorated abstract fields under define semantics while preserving legacy decorator calls, restoring TypeScript 6 behavior.
Changes:
- Adds a synthetic
declaremodifier to abstract properties preserved for the legacy decorator transform. - Adds an ES2022 regression test and baseline showing field erasure with decoration intact.
| File | Description |
|---|---|
tsc/testdata/tests/cases/compiler/legacyDecoratorAbstractPropertyDefine.ts |
Adds regression coverage for decorated abstract fields. |
tsc/testdata/baselines/reference/compiler/legacyDecoratorAbstractPropertyDefine.js |
Records erased fields and the retained __decorate call. |
tsc/internal/transformers/tstransforms/typeeraser.go |
Marks preserved abstract properties with a synthetic declare modifier. |
Review effort: Balanced
| nodes = append(nodes, tx.Factory().NewModifier(ast.KindDeclareKeyword)) | ||
| modifiers = tx.Factory().NewModifierList(nodes) | ||
| } | ||
| return tx.Factory().UpdatePropertyDeclaration(n, modifiers, tx.Visitor().VisitNode(n.Name()), nil, nil, tx.Visitor().VisitNode(n.Initializer)) |
…are not temp-assigned
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 #64980
Problem
With
experimentalDecoratorsand define semantics (useDefineForClassFields, the default at target ES2022+), a decoratedabstractproperty was emitted as a class field. Every instance then got an owndata: undefinedthat shadowed whatever the decorator installed on the prototype. tsc 6.0.3 erased the field.Before:
After:
Cause
For decorated
declare/abstractproperties underexperimentalDecorators,typeeraser.gokeeps the node soLegacyDecoratorsTransformercan emit__decorate. It rebuilds the node withVisitModifiers, which elidesabstract.visitPropertyDeclarationinlegacydecorators.gothen finds neitherNodeFlagsAmbientnorModifierFlagsAbstractand emits a field.declareis unaffected because the node keepsNodeFlagsAmbient.Fix
When preserving a decorated
abstractproperty, append adeclaremodifier so the decorator transform erases the field. This matches Strada, which appendsModifierFlags.Ambientto the preserved node.Tests
Added
legacyDecoratorAbstractPropertyDefine(target ES2022,experimentalDecorators,useDefineForClassFields). The baseline shows no field onBaseand the__decoratecall intact. Also checked manually that the repro printsfalsefrom prototype.