Skip to content

erase decorated abstract properties under experimentalDecorators with define semantics - #64982

Open
Harsh Vardhan Chauhan (1-DARK) wants to merge 2 commits into
microsoft:mainfrom
1-DARK:fix-legacy-decorator-abstract-property-define
Open

Harsh Vardhan Chauhan (1-DARK) wants to merge 2 commits into
microsoft:mainfrom
1-DARK:fix-legacy-decorator-abstract-property-define

Conversation

@1-DARK

Copy link
Copy Markdown
Contributor

Fixes #64980

Problem

With experimentalDecorators and define semantics (useDefineForClassFields, the default at target ES2022+), a decorated abstract property was emitted as a class field. Every instance then got an own data: undefined that shadowed whatever the decorator installed on the prototype. tsc 6.0.3 erased the field.

abstract class Base {
  @dec abstract data: string;
}

Before:

class Base { data; }
// plus the __decorate call

After:

class Base { }
// plus the __decorate call

Cause

For decorated declare/abstract properties under experimentalDecorators, typeeraser.go keeps the node so LegacyDecoratorsTransformer can emit __decorate. It rebuilds the node with VisitModifiers, which elides abstract. visitPropertyDeclaration in legacydecorators.go then finds neither NodeFlagsAmbient nor ModifierFlagsAbstract and emits a field. declare is unaffected because the node keeps NodeFlagsAmbient.

Fix

When preserving a decorated abstract property, append a declare modifier so the decorator transform erases the field. This matches Strada, which appends ModifierFlags.Ambient to the preserved node.

Tests

Added legacyDecoratorAbstractPropertyDefine (target ES2022, experimentalDecorators, useDefineForClassFields). The baseline shows no field on Base and the __decorate call intact. Also checked manually that the repro prints false from prototype.

Copilot AI balanced review requested due to automatic review settings October 27, 2026 21:03
@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.

🟡 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 declare modifier 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))
@typescript-automation typescript-automation Bot added For Backlog Bug PRs that fix a backlog bug and removed For Uncommitted Bug PR for untriaged, rejected, closed or missing bug labels Oct 30, 2026

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 Backlog Bug PRs that fix a backlog bug

Projects

Status: Not started

Development

Successfully merging this pull request may close these issues.

--experimentalDecorators: decorated abstract property is emitted as a class field (regression in 7.0)

2 participants