IVY: Cannot use @Optional in abstract base class
See original GitHub issue🐞 bug report
Affected Package
Is this a regression?
Yes, compiling without IVY works as expected
Description
When you create an abstract base class with a constructor parameter marked with the @Optional decorator, Ivy will not compile because it cannot find a suitable injection token
🔬 Minimal Reproduction
https://github.com/a88zach/ivy-bug/tree/bug/optional
🔥 Exception or Error
ERROR in src/app/app.component.ts:9:27 - error TS-992003: No suitable injection token for parameter 'optionalVar' of class 'AppBaseComponent'.
Found string
9 constructor(@Optional() optionalVar?: string) {
🌍 Your Environment
Angular Version:
Angular CLI: 9.0.0-rc.4
Node: 10.15.3
OS: darwin x64
Angular: 9.0.0-rc.4
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.900.0-rc.4
@angular-devkit/build-angular 0.900.0-rc.4
@angular-devkit/build-optimizer 0.900.0-rc.4
@angular-devkit/build-webpack 0.900.0-rc.4
@angular-devkit/core 9.0.0-rc.4
@angular-devkit/schematics 9.0.0-rc.4
@angular/localize 9.0.0-rc.0
@ngtools/webpack 9.0.0-rc.4
@schematics/angular 9.0.0-rc.4
@schematics/update 0.900.0-rc.4
rxjs 6.5.3
typescript 3.6.4
webpack 4.41.2
Anything else relevant?
This works correctly when you don’t add the @Component decorator to the base class, but due to changes in IVY, @Inputs and other variables marked with Angular decorators no longer work in base classes without the @Component or @Directive decorators applied to the base class
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:6 (2 by maintainers)
Top Results From Across the Web
typescript - Angular 9 do abstract classes for services need the ...
If your base classes don't use Angular features you don't need an Angular decorator. In Angular 9, this requirement is optional; but don't ......
Read more >Missing @Directive()/@Component() decorator migration
This migration adds an empty @Directive() decorator to undecorated base classes that: Use Angular features; Are extended by directives or components.
Read more >Learning the Basics - Gradle User Manual
Gradle will look at the base url location for the POM and the JAR. If the JAR can't be found there, the extra...
Read more >abc — Abstract Base Classes — Python 3.11.1 documentation
A class that has a metaclass derived from ABCMeta cannot be instantiated unless all of its abstract methods and properties are overridden.
Read more >Groovy Language Documentation
reserved keywords can be used for method names if quoted def "abstract"() { true } ... If you use optional typing by using...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

There’s a fair bit going on here, but the crux of this issue is that this is working as intended. Let me break it down a bit.
The need for a decorator on the base class.
This is a known change for Ivy, and there is an
ng updatemigration that does this for you in most cases. In general Ivy requires a top-level decorator on any base class that:@Input()or other Angular decorators on its fields, orThe general recommendation in this case is to add
@Directive()with no arguments (i.e. no selector). Such an “abstract” directive does not need to be declared in anNgModule.Constructor DI validity
This is where your error actually comes from. The constructor in the base class declares a parameter with type
string, which is not a type that the DI system knows how to inject. It doesn’t matter whether the parameter is@Optionalor not - the compiler does not know what token to even ask for in the first place, so it produces this error.In this case, because you’re using an
@Componentdecorator on the base class, the compiler is treating it like a concrete type that the framework might have to create itself, which is why you get a hard error.If you switch to an abstract
@Directive()as mentioned above, this behavior changes. If the constructor is not DI compatible, the compiler instead generates a DI factory that will error at runtime if ever invoked. This means it’s your responsibility when extending from the abstract directive to declare a DI-compatible constructor (and thus callsuper()explicitly), as if you inherit the broken constructor, it will crash at runtime.This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.