GillianPerard / typescript-json-serializer

A typescript library to deserialize json into typescript classes and serialize classes into json.
MIT License
210 stars 29 forks source link

[BUG]: Deserialize returning empty object in string property #200

Closed m4kz closed 1 year ago

m4kz commented 1 year ago

Version

5.1.0

Description

When I deserialize the class below from {"some": "something"}, i get a weird result

uid becomes an empty object, while name is undefined,.

Shouldn't uid also be undefined?

This is the resukt i get:

name: undefined
some: 'something'
uid: {}

Error

No response

Reproduction

class:

@JsonObject()
export class BaseModel {
    @JsonProperty()
    uid?: string;      
    @JsonProperty()
    some?: string|null;
    @JsonProperty() 
    name?: string | null; 
    constructor(uid?: string, some?: string | null, name?: string | null ) {
        this.uid = uid;
        this.some = some;
        this.name = name;
     }
}

Deserialize: const deserializedbm : BaseModel= <BaseModel2>defaultSerializer.deserialize<BaseModel>({"some": "something"}, BaseModel2);

On which OS the bug appears?

Ubuntu

What is your project type?

NodeJs

On which build mode the bug appears?

No response

Anything else?

No response

GillianPerard commented 1 year ago

Hi, thanks for using my lib.

You're right, there is weird behavior there.

Until I fix, you could declare your class as:

@JsonObject()
export class BaseModel {
    @JsonProperty()
    public uid?: string;

    @JsonProperty()
    public some?: string | null;

    @JsonProperty() 
    public name?: string | null;
}
m4kz commented 1 year ago

Thank you. It works, but then i cannot have a constructor.

GillianPerard commented 1 year ago

Yes indeed, let me fix asap.

GillianPerard commented 1 year ago

I checked deeper and there is a problem with Typescript.

You can define a property with multiple possible types, for example: uid: string | undefined but as typescript is not actually a typed language, the type becomes Object in reality.

For a previous PR, I affected a default value equal to {} when I build an instance of the object to deserialize because of people who want to pass an object as constructor params (see: https://github.com/GillianPerard/typescript-json-serializer/issues/161).

I imagine 3 solutions:

m4kz commented 1 year ago

Could be possible to have default configurable? either in JsonProperty? or in JsonSerializer?


const customSerializer = new JsonSerializer({
//Default type
defaultType:  ''
})
GillianPerard commented 1 year ago

Perhaps in the JsonObject, I could create a param to provide default params for the constructor and if no one is set then i provide undefined.

GillianPerard commented 1 year ago

The new version 6.0.0 is here.

You have nothing to do, your could should work now. But I fou want you can specify the default values for the params of your constructor directly inside the JsonObject:

@JsonObject({ constructorParams: [undefined, null, null] })
export class BaseModel {
    @JsonProperty()
    uid?: string;      
    @JsonProperty()
    some?: string|null;
    @JsonProperty() 
    name?: string | null; 

    constructor(uid?: string, some?: string | null, name?: string | null ) {
        this.uid = uid;
        this.some = some;
        this.name = name;
     }
}