为什么打字稿在实现抽象函数时无视严格的空值检查?
Why does typescript disregard strict null checks when implementing abstract functions?
考虑以下摘要class:
export abstract class Foo {
abstract bar(param: string | null): string
}
在具体实现中将参数更改为不可为 null 不会 导致类型错误。这是出乎意料的。
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.
方法参数类型是双向检查的,因此只要实现的参数类型和抽象签名在任一方向相关,它就会进行类型检查(在这种情况下 string
是 [ 的子类型=12=])
您可以使用函数签名语法来避免这种情况,但仅限于接口(派生 类 不能将函数成员实现为方法,不幸的是 ex):
export interface Foo {
bar: (param: string | null) => string
}
export class ConcreteFoo implements Foo{
bar(param: string /* | null */): string { // error
return param!
}
}
目前没有更改此行为的标志(从 TS 4.6 开始)。您可以在引入 strictFunctionTypes
的 PR 中阅读一些有关此决定背后的原因的信息
如果您想了解更多关于方差是什么以及它在打字稿中如何工作的信息,您可以查看我的talk主题
考虑以下摘要class:
export abstract class Foo {
abstract bar(param: string | null): string
}
在具体实现中将参数更改为不可为 null 不会 导致类型错误。这是出乎意料的。
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.
方法参数类型是双向检查的,因此只要实现的参数类型和抽象签名在任一方向相关,它就会进行类型检查(在这种情况下 string
是 [ 的子类型=12=])
您可以使用函数签名语法来避免这种情况,但仅限于接口(派生 类 不能将函数成员实现为方法,不幸的是 ex):
export interface Foo {
bar: (param: string | null) => string
}
export class ConcreteFoo implements Foo{
bar(param: string /* | null */): string { // error
return param!
}
}
目前没有更改此行为的标志(从 TS 4.6 开始)。您可以在引入 strictFunctionTypes
如果您想了解更多关于方差是什么以及它在打字稿中如何工作的信息,您可以查看我的talk主题