【问题标题】:Typescript: undefined calculated property after deserializing in JSON打字稿:在 JSON 中反序列化后未定义的计算属性
【发布时间】:2022-01-23 21:48:39
【问题描述】:

我是 Typescript 新手,遇到了 JSON 反序列化问题。

考虑这个类:

class Product {

    public id!: number;

    public get calculatedProperty() : string {
        return "Test";
    };

};

如您所见,calculatedProperty 是运行时计算的属性。

另外,考虑一下我以这种方式将 JSON 字符串反序列化到我的对象中:

var jsonData = '{ "id": 2 }';
let deserialized = JSON.parse(jsonData) as Product;

问题来了:

  • 此调用console.log(deserialized.id); 正确返回1
  • 此调用console.log(deserialized.calculatedProperty); 返回undefined

我真的不明白。看来as Product并没有真正创建Product对象,因为如果我直接调用构造函数new Product,计算的属性是存在的。

我在 JSON 反序列化方面做错了什么?

谢谢!

【问题讨论】:

    标签: json typescript


    【解决方案1】:

    TypeScript 的工作只是在开发过程中执行类型检查并确保我们不会犯粗心的错误。归根结底,它所做的只是编译脚本并将其转换为好的旧 JavaScript。因此,任何 TypeScript 语法都不会在运行时应用。

    换句话说,type assertions 在运行时被删除。

    文档中也有几个警告:

    像类型注释一样,类型断言被编译器删除,不会影响代码的运行时行为。

    提醒:因为类型断言在编译时被删除,所以没有与类型断言关联的运行时检查。类型断言错误不会产生异常或null

    此外,as 关键字不会实例化构造函数。它仅提供类型信息(将在编译时删除)。我们可以实例化构造函数并访问其实例属性/方法的唯一方法是通过 new 关键字。

    【讨论】:

      【解决方案2】:

      JSON.parse 方法并不是真正用于将 json 转换为类而不是对象。

      要解决您的问题,您可以将 json 转换为如下对象:

      let deserializedObject = JSON.parse(jsonData) as Object;

      然后您可以将对象分配给这样的类:

      let deserialized = Object.assign(new Product(), deserializedObject);

      请注意,我尚未对此进行测试,但它应该可以工作。 这也适用于简单对象,但不适用于具有复杂层次结构的对象。

      查看类转换器以获取更多信息。 https://github.com/typestack/class-transformer

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多