Are there any means for JSON serialization/deserialization of Typescript objects so that they don\'t loose type information? Simple JSON.parse(JSON.stringify)
has t
I think the better way is to use this library. It makes it easier to serialize/deserialize object/json.
https://www.npmjs.com/package/@peerlancers/json-serialization
I think a better way to handle this is to use Object.assign (which however requires ECMAScript 2015).
Given a class
class Pet {
name: string;
age: number;
constructor(name?: string, age?: number) {
this.name = name;
this.age = age;
}
getDescription(): string {
return "My pet " + this.name + " is " + this.age + " years old.";
}
static fromJSON(d: Object): Pet {
return Object.assign(new Pet(), d);
}
}
Serialize and deserialize like this...
var p0 = new Pet("Fido", 5);
var s = JSON.stringify(p0);
var p1 = Pet.fromJSON(JSON.parse(s));
console.log(p1.getDescription());
To take this example to the next level, consider nested objects...
class Type {
kind: string;
breed: string;
constructor(kind?: string, breed?: string) {
this.kind = kind;
this.breed = breed;
}
static fromJSON(d: Object) {
return Object.assign(new Type(), d);
}
}
class Pet {
name: string;
age: number;
type: Type;
constructor(name?: string, age?: number) {
this.name = name;
this.age = age;
}
getDescription(): string {
return "My pet " + this.name + " is " + this.age + " years old.";
}
getFullDescription(): string {
return "My " + this.type.kind + ", a " + this.type.breed + ", is " + this.age + " years old.";
}
static fromJSON(d: Object): Pet {
var o = Object.assign(new Pet(), d);
o.type = Type.fromJSON(o['type']);
return o;
}
}
Serialize and deserialize like this...
var q0 = new Pet("Fido", 5);
q0.type = new Type("dog", "Pomeranian");
var t = JSON.stringify(q0);
var q1 = Pet.fromJSON(JSON.parse(t));
console.log(q1.getFullDescription());
So unlike using an interface, this approach preserves methods.
The AQuirky answer works for me. You may have some troubles with the Object.assign method. I had to modify my tsconfig.json to include:
"compilerOptions": {
...
"lib": ["es2015"],
...
}
First, you need to create an interface of your source entity which you receive from the API as JSON:
interface UserEntity {
name: string,
age: number,
country_code: string
};
Second implement your model with constructor where you can customize (camelize) some field names:
class User {
constructor({ name, age, country_code: countryCode }: UserEntity) {
Object.assign(this, { name, age, countryCode });
}
}
Last create instance of your User model using JS object jsonUser"
const jsonUser = {name: 'Ted', age: 2, country_code: 'US'};
const userInstance = new User(jsonUser);
console.log({ userInstance })
Here is the link to playground
Use Interfaces to get strong types:
// Creating
var foo:any = {};
foo.x = 3;
foo.y='123';
var jsonString = JSON.stringify(foo);
alert(jsonString);
// Reading
interface Bar{
x:number;
y?:string;
}
var baz:Bar = JSON.parse(jsonString);
alert(baz.y);
And use type assertion "<>" if you need to.