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

子类实例b的prop3为何未定义?能否从父类直接赋值该属性?

为什么B实例的prop3是undefined?解决方案详解

原因分析

问题出在TypeScript对类实例属性的编译逻辑上:

  • 当你在子类B中声明prop3?:any时,TypeScript会在编译后的JavaScript代码里,自动在super()调用之后添加一行this.prop3 = undefined,用来初始化这个实例属性。
  • 你的父类A构造函数里用Object.assign(this, o)已经把传入的prop3:'3'赋值给了实例,但子类构造函数执行super()后,立刻执行了this.prop3 = undefined,直接覆盖了之前的值,所以最终prop3变成了undefined。

你可以查看编译后的JS代码,核心逻辑是这样的:

class A {
  constructor(o) {
    Object.assign(this, o);
  }
}
class B extends A {
  constructor(o) {
    super(o); // 这里已经把prop3设为'3'
    this.prop3 = undefined; // TypeScript自动生成的代码,覆盖了之前的赋值
  }
}

解决方案

你不需要必须在子类里额外赋值,有几种方法可以让父类直接完成prop3的赋值:

1. 用接口代替子类的属性声明

如果只是为了TypeScript的类型检查,不需要在子类里显式声明prop3,可以定义一个接口让B实现,这样编译后的代码不会生成this.prop3 = undefined的语句:

interface BInstance extends A {
  prop3?: any;
}

class A {
  prop1?: any;
  prop2?: any;

  constructor(o: any) {
    Object.assign(this, o);
  }
}

class B extends A implements BInstance {
  constructor(o: any) {
    super(o);
  }
}

let b = new B({ prop1: '1', prop2: '2', prop3: '3', prop4: '4' });
console.log(b.prop3); // 输出'3'

2. 子类构造函数中重新合并传入对象

在super()调用后,再次用Object.assign合并传入的对象,覆盖TypeScript自动生成的undefined:

class B extends A {
  prop3?: any;
  constructor(o: any) {
    super(o);
    Object.assign(this, o); // 重新合并,恢复prop3的值
  }
}

3. 用类型断言约束实例类型

如果不需要在类里声明prop3,可以直接用类型断言来告诉TypeScript实例包含prop3:

class A {
  prop1?: any;
  prop2?: any;

  constructor(o: any) {
    Object.assign(this, o);
  }
}

class B extends A {
  constructor(o: any) {
    super(o);
  }
}

// 用类型断言指定实例类型
let b = new B({ prop1: '1', prop2: '2', prop3: '3', prop4: '4' }) as A & { prop3?: any };
console.log(b.prop3); // 输出'3'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 19:45:42