angular: strictTemplates and strictNullChecks doesn't work well with optional chaining in templates
🐞 bug report
Affected Package
The issue is caused by package @angular/compiler?Is this a regression?
?
Description
- enable Ivy
- enable
strictTemplates
- enable
strictNullChecks
- use an expression like
foo?.bar.baz
in a templatefoo
is nullable,bar
is not- template compiler shows error on
baz
:Object is possibly 'undefined'.
- note that the whole chain ends if
foo
is nullish (long short circuiting), therefore accessingbaz
is always safe - disabling
strictNullChecks
makes the compile error go away and everything functions as expected without runtime error (i.e. Angular’s optional chaining also does long short circuiting)
🔬 Minimal Reproduction
https://stackblitz.com/edit/angular-ivy-pu8dk5
🔥 Exception or Error
`Object is possibly 'undefined'.`
🌍 Your Environment
Angular Version:
@angular/animations 9.1.11
@angular/common 9.1.11
@angular/compiler 9.1.11
@angular/core 9.1.11
@angular/forms 9.1.11
@angular/platform-browser 9.1.11
@angular/platform-browser-dynamic 9.1.11
@angular/router 9.1.11
Anything else relevant?
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 16
- Comments: 21 (8 by maintainers)
Reproduction in angular 12.1 https://github.com/sod/ng-strict-issue1 / https://github.com/sod/ng-strict-issue1/blob/master/src/app/app.component.ts
Right now as soon as you use the operator in the template, angular forces you to use it everywhere in that statement, even though, nested structures may be guaranteed to not be undefined by the types.
@JoostK any updates on this?
I think I have similar issue
stackblitz: link
evaluates to string correctly in typescript
but in tempalte it throws
Indeed, the AST restructuring logic happens in the compiler’s output emitter, i.e. the transform from “expression AST” to “output AST”. The typechecker generates TypeScript AST nodes directly from “expression AST” nodes, so it hasn’t gone through that transformation.
FYI I did attempt expanding the translation in the type-checker at one point but never got to finish it; I should have a look at that again.
still an issue on angular 11, I’m bypassing it without using optional chaining, like
*ngIf="foo && foo.bar.baz"