为何TypeScript允许类实现接口时方法参数类型更窄?
为什么这段TypeScript代码能通过编译?
先看你给出的代码:
interface IFoo { foo(a: string | number): void } class Bar implements IFoo { foo(a: string) { } }
你觉得子类Bar的foo方法参数类型string比接口IFoo的string | number更窄,违反可替换性应该报错——这个逻辑本身符合里氏替换原则,但TypeScript默认编译规则允许这种情况,核心原因如下:
- TypeScript对方法参数采用双向协变的检查策略(默认行为)。简单来说,方法参数既可以比父类/接口的参数类型更宽,也可以更窄。这是TypeScript为兼容JavaScript常见写法特意设计的,很多JS代码会只处理部分参数类型,TypeScript默认不强制严格的类型逆变。
- 如果你想严格遵循里氏替换原则,禁止这种参数类型变窄的情况,可以开启TypeScript的
strictFunctionTypes编译选项。开启后这段代码会抛出编译错误,提示Bar的foo方法参数类型不匹配接口要求。
内容的提问来源于stack exchange,提问作者Minh Nghĩa
相关产品推荐
相关产品推荐

