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

TypeScript中使用继承与联合类型实现多态有哪些区别?

TypeScript两种多态实现的核心差异

你提到的「接口方案开放可扩展、联合类型方案封闭有限」是最核心的差异,除此之外两种实现从底层逻辑到实践使用还有很多区别:

理论层面差异

  • 类型判定逻辑不同
    接口是基于*结构子类型(鸭子类型)*设计的,只要对象结构符合Smiley接口的定义(有返回字符串的print方法),哪怕你没有显式写implements Smiley,TS也会认为它是合法的Smiley类型。而联合类型是封闭的类型集合,只有显式声明在Happy | Sad里的类型才算合法,哪怕有第三方类完全实现了print方法,也不属于Smiley联合类型。
  • 多态范式不同
    接口实现的是标准面向对象的子类型多态,严格遵循里氏替换原则,所有实现类都可以无差别替换接口使用。联合类型实现的是函数式编程中常见的代数类型多态,本质是把有限的几种类型打包成一个统一的类型集合使用。

实践层面差异

  • 扩展成本完全相反
    接口方案遵循开闭原则,后续新增Laugh、Awkward等表情类型,不需要修改原有Smiley接口的定义,只要新类实现接口即可。而联合类型方案新增类型时,必须手动修改type Smiley = Happy | Sad | Laugh的定义,所有用到Smiley做类型判断的逻辑也要同步更新。
  • 类型穷尽检查支持不同
    联合类型天然支持TS的穷尽检查,你在switch分支里如果漏了某一种类型的处理,TS会直接给出编译错误,非常适合处理已知固定的有限类型场景。而接口方案无法在编译层面做穷尽检查,漏处理新实现类的问题只能在运行时暴露。
    举个简单的例子:
    // 联合类型版本的穷尽检查,漏了Sad分支会直接报错
    function getSmileyIcon(s: Smiley) {
      switch (s.constructor) {
        case Happy: return '😄';
        default: 
          // 这里如果有未处理的联合类型,s不能赋值给never,TS直接报错
          const _check: never = s;
          throw new Error('未知表情');
      }
    }
    
  • 类型兼容灵活度不同
    接口方案的兼容度更高,你甚至可以直接传入字面量对象{ print: () => ':P' }给接收Smiley接口的函数,不需要提前定义类。而联合类型方案只能传入Happy或者Sad的实例,字面量对象哪怕结构完全匹配也会报类型错误。
  • 耦合度不同
    接口方案的定义和实现完全解耦,不同模块可以独立实现Smiley接口,不需要提前感知彼此的存在。而联合类型的定义必须提前知道所有可能的实现类型,跨模块扩展时耦合度很高。
  • 可继承/实现性不同
    接口可以被类implements,也可以被其他接口extends扩展契约。而联合类型是类型别名,只能用于类型标注,不能被类实现,也不能被继承。

选型参考

如果你的业务场景里类型是固定有限的(比如订单状态、消息类型),选联合类型更安全,能拿到编译层面的穷尽检查保障;如果类型需要支持任意第三方扩展(比如插件系统、公共能力契约),选接口方案更灵活。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 15:45:01