Home > front end >  Typescript: undefined calculated property after deserializing in JSON
Typescript: undefined calculated property after deserializing in JSON

Time:12-23

I'm new to Typescript and I encountered a JSON deserializing problem.

Consider this class:

class Product {

    public id!: number;

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

};

As you can see calculatedProperty is a runtime calculated property.

Also, consider that I deserialize a JSON string into my object in this way:

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

The problem comes now:

  • This call console.log(deserialized.id); returns correctly 1.
  • This call console.log(deserialized.calculatedProperty); returns undefined!

I really don't understand way. It seems that as Product doesn't really create a Product object, because If I directly invoke the constructor, new Product, the calculated property exists.

What am I doing wrong with the JSON deserialization?

Thanks!

CodePudding user response:

TypeScript's job is only to perform type checking during development and make sure we don't make careless mistakes. At the end of the day, all it does is just compiling the script and transform it into good old JavaScript. Therefore, any TypeScript syntax are not applied in runtime.

In other words, type assertions are removed in runtime.

There are also several warnings in the documentation about this:

Like a type annotation, type assertions are removed by the compiler and won’t affect the runtime behavior of your code.

Reminder: Because type assertions are removed at compile-time, there is no runtime checking associated with a type assertion. There won’t be an exception or null generated if the type assertion is wrong.

Besides, the as keyword does not instantiate a constructor. It merely provides a type information (which will be removed during compile-time). The only way we can instantiate a constructor and access its instance properties/methods is through the new keyword.

CodePudding user response:

The JSON.parse method isn't really for converting json into a class rather than an object.

To solve your issue you could potentially convert the json into an object like this:

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

and after that you could assign the object to a class like that:

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

Note that I have not tested this yet, but it should work. Also this is fine for simple objects, but not for objects with complex hierarchy.

Look into class-transformer for more information. https://github.com/typestack/class-transformer

  • Related