Repository navigation
Conversation
A parameter typed `ns.Zero` / `ns.one.One` got `ɵɵinvalidFactoryDep`. Resolve it like ngtsc's `typeToValue`: a namespace import's members read off the emitted namespace (`i1.one.One`), a named import's off its export (`i1.ns.Zero`), and a local namespace's as written. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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 #633.
Problem
A constructor parameter typed with a qualified name (
zero: ns.Zero,one: ns.one.One) gotɵɵinvalidFactoryDep(i), so the class threw when instantiated. Every decorator'sextract_param_tokendroppedTSQualifiedName, even thoughsetClassMetadataalready resolves the same type toi1.one.One.Fix
Resolve the qualified name like ngtsc's
typeToValue(packages/compiler-cli/src/ngtsc/reflection/src/type_to_value.ts): the leftmost name decides.import * as ns: the members are read off the emitted namespace import (i1.Zero,i1.one.One).import {ns}/import {ns as alias}: they are read off the export (i1.ns.Zero).local.L,entityNameToValue).@Injectable,@Directive,@Pipeand@NgModulenow build the token as a member chain (util::type_name_to_value_expr), andresolve_factory_dep_namespacesresolves the chain through its root. Components keep tokens as names, so their dependency getstoken_member_pathandtoken_is_namespace_import; the partial declaration emits the token as written (token: ns.one.One).Side effect: because
resolve_factory_dep_namespacesnow resolves member chains, an@Inject(ns.TOKEN)argument rooted at an import also goes through the namespace import (i1.TOKEN) instead ofns.TOKEN. Plain@Inject(TOKEN)identifiers were already handled this way. The two forms are equivalent at runtime. This also fixes@Inject(mod.T)for a named import withemit_class_metadata: false: import elision removed themodimport and leftmod.Tunbound.Checks
tests/namespaced_ctor_token_test.rsports both ngtsc spec cases ("...type references to namespaced symbols using a namespace import" / "...using named imports"). It also covers a local namespace, Component/Directive/NgModule/Pipe factories, and the partial component declaration. All 5 tests fail onmainand pass with the fix.cargo test -p oxc_angular_compiler --all-features: 3521 passed, 0 failed, 1 ignored.cargo fmt --checkpasses.cargo clippy -p oxc_angular_compiler --all-featuresreports no warnings on the changed lines.🤖 Generated with Claude Code