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"