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

子类用super访问抽象类protected属性运行报错,TypeScript无类型错误

为什么子类中通过super.service访问父类protected实例属性会报错?

问题描述

在TypeScript中,子类尝试通过super访问父类的protected实例属性时,运行时会抛出TypeError: Cannot read properties of undefined (reading 'do'),但TypeScript类型检查不会报错。仅使用this访问时一切正常。

示例代码:

interface Service {
  do(): void;
}

abstract class Abstract {
  constructor(protected readonly service: Service) {}

  abstract execute(): void;
}

class Concrete extends Abstract {
  constructor(service: Service) {
    super(service);
  }

  execute(): void {
    super.service.do(); // 替换为this.service即可正常运行
  }
}

class ServiceImpl implements Service {
  do(): void {
    console.log("i saved something");
  }
}

const concrete = new Concrete(new ServiceImpl());
concrete.execute(); // 运行时抛出错误

运行时错误:

TypeError: Cannot read properties of undefined (reading 'do')

原因分析

  1. JavaScript类属性的运行机制:
    父类Abstract中的service是实例属性,在构造函数中声明后,实际是在实例化时直接赋值给this(即子类实例),并不会挂载到父类的原型对象上。
    当使用super.service时,JavaScript会去父类的原型上查找service属性,但父类原型上并没有这个属性,因此返回undefined。

  2. TypeScript类型检查的偏差:
    TypeScript的类型系统允许通过super访问父类的protected成员,这是从类型层面表明该成员来源于父类,但它没有区分原型属性和实例属性的运行时差异,导致类型检查不报错,但实际运行不符合预期。

解决方案

方案1:直接使用this.service

这是最简洁且符合运行逻辑的方式,service本身就是挂载在实例(this)上的属性,子类实例可以直接通过this访问父类的protected成员:

execute(): void {
  this.service.do(); // 正常运行
}

方案2:用JSDoc注释明确属性来源

如果想让其他开发者快速识别service来自父类,可以添加JSDoc注释说明,既不影响运行,又能提升可读性:

execute(): void {
  /** @type {Service} 继承自父类Abstract的protected属性 */
  this.service.do();
}

方案3:将父类属性改为原型getter(可选)

如果一定要通过super访问,可以将父类的service改为原型上的getter方法,让super.service能正确指向父类原型的getter,最终返回实例上的属性:

abstract class Abstract {
  private readonly _service: Service;

  constructor(service: Service) {
    this._service = service;
  }

  // 定义原型getter
  protected get service(): Service {
    return this._service;
  }

  abstract execute(): void;
}

class Concrete extends Abstract {
  execute(): void {
    super.service.do(); // 现在可正常运行
  }
}

这种方式略显冗余,仅为满足super访问的需求,一般不推荐常规场景使用。


内容的提问来源于stack exchange,提问作者Davi Banfi Nogueira

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 10:24:54