Conversation
mattrbeck
marked this pull request as ready for review
September 18, 2026 01:05
crisbeto
approved these changes
Sep 18, 2026
| (typeof ngDevMode === "undefined" || ngDevMode) && $i0$.傻setClassMetadata(CustomInjectable, [{ | ||
| type: Injectable | ||
| }], () => [{ | ||
| }], //@ts-ignore |
Member
There was a problem hiding this comment.
Wouldn't we have to put this on top of type: Service?
Member
Author
There was a problem hiding this comment.
Updated to place it right on the type: Service assignment
| * This prevents hard compile errors (TS2339, TS2693, TS2708) in single-file or downstream | ||
| * typechecking environments when type-only symbols (e.g. interfaces) appear in value position. | ||
| */ | ||
| function compileCtorParameters(ctorParameters: o.Expression | null): o.Expression { |
Member
There was a problem hiding this comment.
Would it make sense to do this when metadata.ctorParameters is constructed for the first time?
Member
Author
There was a problem hiding this comment.
metadata.ctorParameters is constructed in angular/compiler-cli today. ngp calls compileClassMetadata and doesn't go through the cli, so I think we have to do the work to inspect the AST here, unfortunately :/ In any case, I've updated it to apply directly to the type: Service rather than the map overall!
mattrbeck
force-pushed
the
fix-compiler-setclassmetadata-ts-ignore
branch
from
September 18, 2026 22:41
a2b7b5c to
9327537
Compare
mattrbeck
force-pushed
the
fix-compiler-setclassmetadata-ts-ignore
branch
6 times, most recently
from
September 19, 2026 15:44
1c2c5ab to
9ceb996
Compare
In local compilation mode the compiler can emit a reference to a symbol that it was not able to prove has a value at runtime, because deciding that can require information from other files. The generated factory already guards those references with a `@ts-ignore`, but the `ctorParameters` callback passed to `setClassMetadata` does not, so the same symbol ends up guarded in one place and unguarded a few lines later in the same file. Type checking the generated code then fails on the unguarded reference. Constructor parameters are now handed to `@angular/compiler` in a structured form rather than as an already-built callback, which lets the compiler attach a suppression directly to the `type` property assignment of each parameter that needs one. Only references that reflection could not verify are guarded: full compilation resolves every reference, so its output is unchanged, and partial declarations are published as JavaScript and never type checked, so they are never guarded either. Producers that build the callback themselves keep passing an expression, which is emitted untouched.
mattrbeck
force-pushed
the
fix-compiler-setclassmetadata-ts-ignore
branch
from
September 19, 2026 19:47
9ceb996 to
7729e4c
Compare
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.
What is the current behavior?
In local compilation (or single-file compilation without whole-program type information), the compiler emits references to constructor dependency symbols into value positions in
setClassMetadatawithout being able to confirm that they exist at runtime.While the generated factory (
傻fac) already guards unverified references with@ts-ignore, thectorParameterscallback insetClassMetadatadoes not. When downstream TypeScript compilation runs, type-only symbols (e.g. interfaces) emitted into thectorParameterscallback fail with compile errors (TS2339,TS2693,TS2708).What is the new behavior?
Constructor parameters can now be provided to
@angular/compilerin a structured format (R3ClassMetadataCtorParameter[]) in addition to pre-built expressions. When provided in structured form, the compiler generates thectorParameterscallback and attaches a@ts-ignoredirectly to thetypeproperty assignment of unverified parameters.valueUnverifiedis false and output remains bit-for-bit unchanged.allowSuppressions: falseand are never guarded.o.Expression, which is emitted untouched.Notes for reviewers
typeproperty vs callback:@ts-ignoreonly suppresses errors on the immediately following line. A guard above the callback would fail to reach later parameters if decorators or arguments span multiple lines. Attaching directly to thetypeproperty assignment ensures the suppression stays on the type reference line regardless of multi-line object formatting.R3ClassMetadataCtorParameter[]in@angular/compilerallows compiler consumers to share canonical parameter metadata lowering without duplicating callback AST construction or comment trivia logic.