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

TypeScript中向期望基类对象的函数传入派生类对象的问题

TypeScript回调打印属性不符预期的问题排查与解决

问题描述

我从C转向TypeScript项目,想要实现C中向期望基类对象的函数传入派生类对象的典型行为,编写了如下代码:

export interface MyInterface {
    myFlag: boolean;
}

class MyInterfaceImpl implements MyInterface {
  private _myFlag: boolean;

  constructor(){
    // 示例初始化逻辑
    this._myFlag = false;
  }

  get myFlag() {
        return this._myFlag;
    }
  set myFlag(value: boolean) {
        this._myFlag = value;
        
        onMyCallbackFunc(this);
    }
}

export function onMyCallbackFunc(myBaseObject : MyInterface) {
    console.log(`${JSON.stringify(myBaseObject)}`);
}

调用回调函数时,控制台打印的是{"_myFlag": true}而非预期的{"myFlag": true},请问问题出在哪?

问题原因

  1. JSON.stringify的行为限制:JSON.stringify只会序列化对象自身的可枚举自有属性,不会主动调用对象的getter访问器。你的类中_myFlag是私有但默认可枚举的实例属性,而myFlag是getter/setter形式的访问器属性,默认不会被JSON.stringify识别并序列化。
  2. TypeScript接口的编译时特性:MyInterface仅作为编译阶段的类型约束,运行时不存在任何实际的接口对象,所以onMyCallbackFunc中的类型标注不会改变传入对象的本质——依然是MyInterfaceImpl的实例,包含_myFlag私有属性。

解决方法

方法1:让访问器属性可枚举

通过Object.defineProperty显式将myFlag访问器设置为可枚举,这样JSON.stringify就会处理它:

class MyInterfaceImpl implements MyInterface {
  private _myFlag: boolean;

  constructor(){
    this._myFlag = false;
    // 显式配置访问器的可枚举性
    Object.defineProperty(this, 'myFlag', {
      enumerable: true,
      get: () => this._myFlag,
      set: (value) => {
        this._myFlag = value;
        onMyCallbackFunc(this);
      }
    });
  }
}

方法2:自定义toJSON方法

在类中实现toJSON方法,手动指定序列化时要输出的属性结构,这是最灵活的方案:

class MyInterfaceImpl implements MyInterface {
  private _myFlag: boolean;

  constructor(){
    this._myFlag = false;
  }

  get myFlag() {
        return this._myFlag;
    }
  set myFlag(value: boolean) {
        this._myFlag = value;
        
        onMyCallbackFunc(this);
    }

  // 自定义序列化逻辑
  toJSON() {
    return {
      myFlag: this.myFlag
    };
  }
}

此时JSON.stringify会自动调用toJSON方法,输出符合预期的{"myFlag": true}。

方法3:回调中手动转换对象

在回调函数里,基于接口类型手动构建要序列化的对象,避免直接序列化实例:

export function onMyCallbackFunc(myBaseObject : MyInterface) {
    const output = {
        myFlag: myBaseObject.myFlag
    };
    console.log(JSON.stringify(output));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 13:50:48