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

TypeScript 2.7.2中为何不同类型参数调用函数在Angular6中无报错?

为什么将B类实例传给要求A类型的函数时没有报错?

在使用TypeScript 2.7.2的Angular 6项目中,我遇到了这样的情况:调用参数类型为A的func2函数时传入了B类实例,但既没有IDE错误,也没有--aot编译错误。相关代码如下:

函数调用代码

private func1() { 
  const b: B = new B(); 
  b.name = 'jack'; 
  this.func2(b); 
}
private func2(a: A) { 
  console.log(a.name); // 输出 jack 
}

类定义

export class A { public name: string; }
export class B { public name: string; public surname: string; }

这是因为TypeScript采用的是结构类型系统(Structural Typing),而不是Java、C#这类语言常用的名义类型系统(Nominal Typing),具体原因可以拆解为两点:

  • TypeScript判断类型兼容性的核心依据是结构匹配,而非类名:只要一个类型拥有目标类型要求的所有属性和方法(结构是目标类型的超集),就允许互相赋值。这里B类不仅包含了A类的所有属性(name: string),还多了surname属性,完全满足func2对参数类型A的要求,所以TS认为这个赋值是合法的。
  • IDE的实时类型检查和Angular的--aot编译都是基于TypeScript的类型规则实现的,自然会遵循这种结构兼容的逻辑,因此不会抛出错误。

如果想要强制实现名义类型(让A和B即使结构重叠也不能互相赋值),可以给每个类添加一个唯一的私有标识属性来区分:

export class A { 
  public name: string;
  private readonly _type: 'A' = 'A'; // 唯一私有标识
}
export class B { 
  public name: string; 
  public surname: string;
  private readonly _type: 'B' = 'B'; // 唯一私有标识
}

此时两个类的私有属性_type类型不同,结构不再兼容,再把B实例传给func2就会触发TypeScript的类型错误了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:55:46