You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么TypeScript允许继承的方法不完整实现接口要求?

类型检查器判定初始代码合法的核心原因

这是TypeScript的默认设计:类和接口中使用方法语法定义的函数,参数类型默认采用双变(Bivariance)兼容规则。
先明确类型关系:你定义的AB是B的子类型,AB包含B的全部字段,还额外存在a字段。
按照严格的类型理论,函数参数的兼容性应该遵循逆变规则:如果要求实现一个(x: B) => void类型的方法,提供的实现参数类型必须是B或者B的父类型(可以接收更宽泛的参数),不能是B的子类型(只能接收更窄的参数)。按这个规则,Superclass的foo方法类型是(x: AB) => void,无法兼容接口I要求的(x: B) => void,理应触发报错。
但TypeScript为了兼容JavaScript生态中大量常见的宽松用法(比如数组协变、经典的类继承模式),默认对方法参数关闭了严格逆变检查,只要两个参数类型存在子父类关系,无论方向都认为兼容,这就是你初始代码没有报错的原因。

如果你想要触发你预期的严格检查,可做两个调整:

  1. 在tsconfig.json中开启strictFunctionTypes编译选项(属于strict模式的子配置项)
  2. 将接口中的方法定义为函数字面量形式:
interface I {
    foo: (x: B) => void;
}

调整后初始代码会直接抛出类型错误,提示Subclass实现的foo方法不满足接口I的要求。

为什么子类显式实现foo方法时调用super.foo会报错

这个检查和双变规则无关,是普通的实参类型匹配检查:super.foo要求入参是AB类型,你传入的是B类型,B不是AB的子类型(缺少a字段),自然会触发类型错误。

内容的提问来源于stack exchange,提问作者Martin Geisse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 00:24:01