Angular Ivy strictTemplates true 下,类型“boolean | null”无法分配给类型“boolean”。

43

我已经将我的应用程序更新到9版本。 一切都很好,但我遇到了strictTemplates设置为true的问题。 例如,这段代码

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

我遇到了错误,提示“Type 'boolean | null' is not assignable to type 'boolean'”。

这个修复可以解决这个错误。

@Input() loaded!: boolean | null;

但是我看不出来重点,有人能解释一下吗?

3个回答

91
原因是由于async管道的返回值签名类似于<T>(input$: Observable<T>): T | null,因为它在等待异步调用的响应时向模板返回null。
更多信息请参阅: https://angular.io/guide/template-typecheck#strict-null-checks 你可以像之前做的那样允许null,或者如果你知道它永远不会为null,可以使用非空断言运算符。
[loaded]="(loaded$ | async)!"

或者在此处禁用类型检查:

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

对于这个特定的情况,你可以尝试像这样做:

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

4
最好具体解决问题,而不是使用断言操作符或任意转换来掩盖它。我喜欢[loaded]="!!(loaded$ | async)",它始终是一个布尔值,在模板中比Boolean(x)更短且有效。 - Coderer
2
我基本上同意强制转换正确的类型是正确的方法(如第三个选项),因为这样你的组件永远不会接收到错误的类型,但并不是每种情况都像将 null 强制转换为布尔值那么简单,所以我想提供处理这种情况的所有选项。 - bryan60
非常好的观点。如果我不提及此相关问题,那我就有些失职了——看起来我们很快会在模板中获得空位合并运算符(??)的访问权限,这太棒了。 - Coderer

1
这更像是TypeScript更新错误,而不是Angular更新。我认为,在TypeScript 2X版本之后,nullundefined不再是其他类型的子类型了。这一直都是为了提供更多的编译时静态类型检查。
如果你的实际类型是布尔值,并且你收到了null,那么它不会对你产生太大影响。但是,如果你的实际类型是对象,那么你必须感到欣慰,因为TypeScript会强制你进行所有真值检查,以便你不会遇到运行时错误。
事实上,JavaScript中的所有东西都是对象,但我们通常不将布尔值用作对象。但如果我们使用:

let a = true;
console.log(a.toString());
a = null;
console.log(a.toString());


@user3887366 但是私信中应该会认同这种方式使代码更加健壮。 - Ashish Ranjan

0

您可以使用asyncy管道,该管道在内部使用async管道,但返回T类型而不是T | null


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接