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

TypeScript继承:父类使用、仅子类定义的数据成员应如何声明

原代码问题梳理

原代码存在两处核心问题:

  • 父类some_function方法存在笔误,将this.value写为this.val,运行时会直接抛出未定义错误
  • 父类声明的protected value: number未在父类构造函数中初始化,仅在子类中赋值,若父类方法在子类初始化完成前被调用,会拿到undefined,和声明的number类型冲突,触发运行时异常
正确实现方案

方案1:使用抽象类+抽象属性(最推荐)

如果该属性必须由所有继承的子类提供,父类本身不需要也不能直接实例化,直接将父类定义为抽象类,属性声明为抽象属性,强制子类必须实现该属性,TS编译阶段就会做检查,从根源避免属性未赋值的问题:

abstract class Parent {
  foo: number;
  // 声明抽象属性,强制所有子类必须实现该属性
  protected abstract value: number;
  constructor(foo: number) { 
    this.foo = foo 
  }
  some_function() { 
    return this.foo + this.value 
  }
}

class ChildClass extends Parent {
  // 子类必须实现抽象属性,否则TS会直接编译报错
  protected value: number;
  constructor(foo: number) { 
    super(foo); 
    this.value = 10;
  }
}

方案2:属性声明为允许undefined类型,使用时加类型守卫

如果父类需要支持直接实例化,没有强制要求子类必须传该属性,可以明确声明属性可能为undefined,用到的地方做兼容处理:

class Parent {
  foo: number;
  // 明确声明value可能为undefined
  protected value: number | undefined;
  constructor(foo: number) { 
    this.foo = foo 
  }
  some_function() { 
    // 加类型守卫,处理属性未赋值的情况
    if (this.value === undefined) {
      throw new Error('value属性未初始化,请先完成赋值再调用该方法');
      // 也可以设置 fallback 逻辑:return this.foo + 0
    }
    return this.foo + this.value 
  }
}

class ChildClass extends Parent {
  constructor(foo: number) { 
    super(foo); 
    this.value = 10;
  }
}

方案3:父类给属性设置默认值

如果该属性有通用的默认值,可以直接在父类中设置默认值,子类可以选择是否覆写:

class Parent {
  foo: number;
  // 父级设置默认值
  protected value: number = 0;
  constructor(foo: number) { 
    this.foo = foo 
  }
  some_function() { 
    return this.foo + this.value 
  }
}

class ChildClass extends Parent {
  constructor(foo: number) { 
    super(foo); 
    // 子类覆写默认值
    this.value = 10;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 19:36:04