为啥打字稿在实现抽象函数时忽略严格的空检查?

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】:

方法参数类型被双变量检查,所以只要实现的参数类型和抽象签名在任一方向相关,它就会类型检查(在这种情况下stringstring | 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 函数中动态导入类的正确方法是啥?

使用严格的空检查处理 Typescript 2.0 中的数组移位返回类型

打字稿在编译时减去两个数字

打字稿在元组联合中缩小范围