Angular Ivy strictTemplates true Type 'boolean | null' is not assignable to type 'boolean'
Asked Answered
T

3

45

I've updated my app to 9 version. Everything is alright but I've problem with strictTemplates set to true. For instance this code

loaded$: Observable<boolean>
[loaded]="loaded$ | async"
@Input() loaded!: boolean;

I've got the error Type 'boolean | null' is not assignable to type 'boolean'.

This fix the error

@Input() loaded!: boolean | null;

But I cant see the point someone acn explain me, please?

Trifolium answered 13/5, 2020 at 16:51 Comment(0)
B
100

The reason is because the async pipes return signature is something like <T>(input$: Observable<T>): T | null always, because it returns null to the template while it's awaiting a response from an asynchronous call.

More about this here: https://angular.io/guide/template-typecheck#strict-null-checks

You can do what you've done and allow null, or if you know it will never be null, use a non null assertion operator:

[loaded]="(loaded$ | async)!"

or disable type checking here:

[loaded]="$any(loaded$ | async)"

or for this particular case you could probably do something like this:

[loaded]="(loaded$ | async) || false"
Bertold answered 13/5, 2020 at 17:28 Comment(3)
Better to address the issue specifically than to mask it with the assertion operator or any-casting. I like [loaded]="!!(loaded$ | async)", which is always a boolean, shorter than Boolean(x) and works in templates.Gazehound
I generally agree that coercing the proper type is the way to go (as in the third option), as that way your component can never receive the wrong type, but not every case will be as simple as coercing a null to boolean, so I wanted to give all the options for handling this situationBertold
Great point. I would be remiss if I didn't mention this related issue -- it looks like we'll soon get access to the nullish coalescing operator (??) in templates, which is greatGazehound
G
1

This is more of Typescript update error than an Angular update, I believe, after Typescript 2X versions, null and undefined are no more subtypes of other types, and this is as always to provide more compile-time. static type check.

It wouldn't affect you much if your actual type was a boolean and you received as null but had your actual type been an Object, you must be releived that Typescript would force you to do all truthy checks so that you do not fall into runtime errors.

And as it turns out everything in Javscript is an Object, but we usually do not use boolean as an Object but if we use:

let a = true;
console.log(a.toString());
a = null;
console.log(a.toString());
Gawk answered 13/5, 2020 at 16:59 Comment(1)
@Trifolium But it should be okay to the PM that the code is more robust this way.Gawk
T
0

you can use asyncy pipe that uses async pipe internally but returns T type instead of T | null.

Thorbert answered 27/4, 2023 at 20:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.