为啥打字稿在实现抽象函数时忽略严格的空检查?
Posted
技术标签:
【中文标题】为啥打字稿在实现抽象函数时忽略严格的空检查?【英文标题】:Why does typescript disregard strict null checks when implementing abstract functions?为什么打字稿在实现抽象函数时忽略严格的空检查? 【发布时间】:2022-01-15 01:34:23 【问题描述】:考虑以下抽象类:
export abstract class Foo
abstract bar(param: string | null): string
在具体实现中将参数更改为不可为空不会导致类型错误。这是出乎意料的。
export class ConcreteFoo extends Foo
bar(param: string): string
return param
这让我可以这样做:
const inst = new ConcreteFoo() as Foo
const res = inst.bar(null)
console.log(res) // res is null, but typescript says it is string
为什么会这样?
严格的空值检查已开启。 打字稿版本是 4.5.3。
【问题讨论】:
【参考方案1】:方法参数类型被双变量检查,所以只要实现的参数类型和抽象签名在任一方向相关,它就会类型检查(在这种情况下string
是string | null
的子类型)
您可以使用函数签名语法来避免这种情况,但仅限于接口(不幸的是,派生类无法将函数成员实现为方法ex):
export interface Foo
bar: (param: string | null) => string
export class ConcreteFoo implements Foo
bar(param: string /* | null */): string // error
return param!
Playground Link
目前没有改变这种行为的标志(从 TS 4.6 开始)。您可以在介绍 strictFunctionTypes
的 PR 中了解此决定背后的原因
如果您想了解更多关于什么是方差以及它在打字稿中的工作原理,您可以查看我的talk 主题
【讨论】:
以上是关于为啥打字稿在实现抽象函数时忽略严格的空检查?的主要内容,如果未能解决你的问题,请参考以下文章
使用打字稿在 Firebase Cloud 函数中动态导入类的正确方法是啥?