feature: Top level abstract class parsing
Description
I have an abstract type with child classes which i receive from the server. I would like to transform that directly into its proper class without having to write my own parse method
This works when the main class has a variable that is annotated using @Type obviously, however this doesnt help me when the object is just a Photo.
Example json:
{
type: "Landscape",
id: 634,
filename: "myphoto.jpeg"
}
import { Type, plainToClass } from 'class-transformer';
export abstract class Photo {
id: number;
filename: string;
}
export class Landscape extends Photo {
panorama: boolean;
}
export class Portrait extends Photo {
person: Person;
}
export class UnderWater extends Photo {
depth: number;
}
let photo = plainToClass(Photo, photoJson);
// now photo needs to be whichever subtype
Currently i have to write something like this:
public static parse(data: any): Photo{
if (data.type == PhotoType.Landscape ) {
return plainToInstance(Landscape, data) as any;
} else if (data.type == PhotoType.Portrait ) {
return plainToInstance(Portrait , data) as any;
}
}
Proposed solution
A class annotation for decorors, possibly similar to this repo: https://github.com/edcarroll/ta-json#usage-4
To add to this, is also really similar pattern to resolving Unions in type-graphql (and graphql in more constructive manners). Would think this could be done via like so:
Type-graphql already does this
https://typegraphql.com/docs/unions.html#resolving-type
Hello @kwek20,
I assume you would like to extend the current discriminator solution to work on the base abstract class level as well? Is that right? So you would like to do something like:
@Type({
discriminator: {
property: '__type',
subTypes: [
{ value: Landscape, name: 'landscape' },
{ value: Portrait, name: 'portrait' },
{ value: UnderWater, name: 'underwater' },
],
},
})
export abstract class Photo {
id: number;
filename: string;
}
export class Landscape extends Photo {
panorama: boolean;
}
export class Portrait extends Photo {
person: Person;
}
export class UnderWater extends Photo {
depth: number;
}
let album = plainToInstance(Photo, photoJson);
@diffy0712 yes that is correct! This would also mean not having to copy/ref the discriminator on each class that has the type. Im a bit suprised about the reply though, i thought this project was on hold. Good to see life again!
Thank you for the reply,
I still have to check if there were any discussion on this topic already, but I think this could be useful.
I myself would have already needed this feature too :)
We try to get some work done on class-transformer, hopefully we will have time to do so :)
@kwek20 there is already a really old discussion and pr on this topic. I will try to read through the issue and the pr and maybe we can do something with it.
Duplicate of https://github.com/typestack/class-transformer/issues/223