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},请问问题出在哪?
问题原因
- JSON.stringify的行为限制:
JSON.stringify只会序列化对象自身的可枚举自有属性,不会主动调用对象的getter访问器。你的类中_myFlag是私有但默认可枚举的实例属性,而myFlag是getter/setter形式的访问器属性,默认不会被JSON.stringify识别并序列化。 - 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
相关产品推荐
相关产品推荐

