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

如何防止对象赋值、JSON反序列化时丢失类装饰器及元数据?

核心问题场景

问题1:对象字面量冒充类实例丢失元信息

直接用普通对象字面量创建类类型的变量时,不会走类的构造函数逻辑,也不会保留类上挂载的装饰器、原型方法等元信息,示例代码:

@jsonReflect()
class TestClass {
    name?: string;
    age?: number;
    @jsonIgnore()
    address?: string;
}
// 该写法生成的是普通Object,不是TestClass的实例
const test = { name : "John", age: 10 };

问题2:JSON.parse反序列化结果丢失类元信息

JSON.parse的返回值永远是原生普通JavaScript对象,哪怕给它加上TypeScript类型标注,运行时也不会自动转换为对应类的实例,类上的装饰器规则、构造逻辑、元数据会完全丢失,导致后续序列化不符合预期,示例代码:

export class ConnectorSignature {
    name!: string;
    dataType!: string;
    @jsonIgnore()
    dataReference!: number;
}

// 仅为编译时类型标注,运行时connectorData是普通对象
const connectorData: ConnectorSignature = JSON.parse('{"name":"Blue","dataType":"Integer","dataReference":2}');

// 序列化时@jsonIgnore规则完全失效,会输出所有字段
console.log(JSON.stringify(connectorData));
// 输出结果:{"name":"Blue","dataType":"Integer","dataReference":2}

注意:TypeScript的类型标注仅在编译阶段生效,运行时会被完全擦除,不存在任何类型转换逻辑,直接给普通对象加类类型标注本质是类型欺骗,不会改变对象的实际运行时结构。


解决方案

阻止对象字面量冒充类实例

  • 给类增加独有的私有标识字段,从TypeScript编译层面拦截非法赋值:
    @jsonReflect()
    class TestClass {
      // 私有字段是类独有的,普通对象字面量不可能自带该字段
      readonly #_brand = 'TestClass' as const;
      name?: string;
      age?: number;
      @jsonIgnore()
      address?: string;
    }
    // 此时TS会直接报类型错误,不允许将普通对象赋值给TestClass类型变量
    const test: TestClass = { name : "John", age: 10 };
    
  • 配置ESLint校验规则,开启@typescript-eslint/no-unsafe-assignment、@typescript-eslint/no-explicit-any等规则,禁止无转换的普通对象到类类型的直接赋值,在代码检查阶段拦截不规范写法。

解决反序列化元信息丢失问题

  • 禁止直接将JSON.parse的返回值断言为类类型,所有类实例的反序列化必须走显式实例化逻辑:解析完JSON普通对象后,手动new出对应类的实例,再将字段逐一赋值到实例上,确保生成的是真正的类实例,示例:
    function parseConnectorSignature(jsonStr: string): ConnectorSignature {
      const raw = JSON.parse(jsonStr);
      const instance = new ConnectorSignature();
      instance.name = raw.name;
      instance.dataType = raw.dataType;
      instance.dataReference = raw.dataReference;
      return instance;
    }
    
    const connectorData = parseConnectorSignature('{"name":"Blue","dataType":"Integer","dataReference":2}');
    // 此时connectorData是真正的ConnectorSignature实例,装饰器规则可以正常生效
    console.log(connectorData instanceof ConnectorSignature); // true
    
  • 项目中类序列化/反序列化场景较多时,统一使用支持装饰器规则的序列化工具类接管所有JSON转换逻辑,替换原生JSON.parse和JSON.stringify:工具会自动识别类上的装饰器配置,反序列化时自动生成对应类的合法实例,序列化时自动跳过标记为忽略的字段,无需手动编写每个类的转换逻辑。
  • 增加运行时校验:所有反序列化生成的实例,在使用前通过instanceof做类型校验,拦截漏走转换逻辑的异常数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 05:39:15