fix(compiler-cli): record class extends clause references in DeferredSymbolTracker - #70111
Open
mattrbeck wants to merge 1 commit into
Open
fix(compiler-cli): record class extends clause references in DeferredSymbolTracker#70111mattrbeck wants to merge 1 commit into
mattrbeck wants to merge 1 commit into
Conversation
…SymbolTracker `DeferredSymbolTracker.lookupIdentifiersInSourceFile` prunes `ts.isTypeNode` subtrees so that references appearing exclusively inside type annotations do not keep static import declarations in the emitted JavaScript. However, `ts.isTypeNode` returns `true` for `ts.ExpressionWithTypeArguments`, which TypeScript uses to represent both `extends` and `implements` heritage clauses. An `extends` clause on a class declaration or class expression is a value position that survives in the emitted JavaScript output. Because `isTypeNode` returned `true`, references to base classes imported alongside deferred dependencies were ignored. As a result, the compiler erroneously marked the static import statement as deferrable and deleted it from the emitted JavaScript, leaving the `extends <Base>` clause referencing an undeclared identifier and causing a runtime `ReferenceError`. This commit ensures that `ExpressionWithTypeArguments` under a class `extends` clause is not treated as an erasable type node, preserving the static import whenever a base class is referenced.
mattrbeck
force-pushed
the
fix-defer-extends-reference
branch
from
August 7, 2026 00:36
4830ee1 to
18d899e
Compare
mattrbeck
marked this pull request as ready for review
August 7, 2026 00:51
Member
Author
|
Passing g3 tests. Currently running TGP, although expecting this not to be breaking http://test/OCL:960612740:BASE:960633940:1786073167024:52dfa045 |
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.
Problem
DeferredSymbolTracker.lookupIdentifiersInSourceFileprunests.isTypeNodesubtrees so that references appearing exclusively inside type annotations do not prevent static import declarations from being elided in favor of@deferdynamicimport()s.However,
ts.isTypeNodereturnstrueforts.ExpressionWithTypeArguments, which TypeScript's AST uses to represent bothextendsandimplementsheritage clauses. Anextendsclause on a class declaration or class expression is a runtime value position that survives into emitted JavaScript:Because
isTypeNodereturnedtrueforts.ExpressionWithTypeArguments, references toBaseComponentwere pruned.DeferredSymbolTrackerconcluded thatBaseComponenthad zero runtime references, marked the static import as deferrable, and deleted it from the emitted JavaScript output.At runtime, this results in a fatal
ReferenceError: BaseComponent is not defined.Solution
Ensure that
ExpressionWithTypeArgumentsrepresenting anextendsclause on a class declaration or class expression is not treated as an erasable type node inlookupIdentifiersInSourceFile. References within a classextendsclause are now properly recorded as active runtime references, preventing the static import from being deleted when a base class is referenced.Testing
Added a new compliance test case in
packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/:defer_extends_clauseverifying that static imports are preserved and the dependency is emitted eagerly when a sibling symbol is referenced in a classextendsclause.