Open getlarge opened 3 years ago
Tip: While that solutions are not implemented I'm using the generic @Transform decorator to convert to the specific classes. Example with top-level param:
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;
}
enum TopPhotoType {
'landscape' = 'landscape',
'portrait' = 'portrait',
'underwater' = 'underwater'
}
const topPhotoTypeMap: { [key in TopPhotoType]: new () => Photo } = {
'landscape': Landscape,
'portrait': Portrait,
'underwater': UnderWater
}
export class Album {
id: number;
name: string;
topPhotoType: TopPhotoType;
@Transform(
({ value, obj }) => {
const specificClass = topPhotoTypeMap[obj.topPhotoType];
return plainToInstance(specificClass, value);
},
{
toClassOnly: true
}
)
@Type(() => Object)
topPhoto: Landscape | Portrait | UnderWater;
}
let album = plainToClass(Album, albumJson);
To make @jonasof solution even more useful i suggest to also resolve the dynamic type so that @ValidateNested can also be used. To continue with his example:
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;
}
enum TopPhotoType {
'landscape' = 'landscape',
'portrait' = 'portrait',
'underwater' = 'underwater'
}
const topPhotoTypeMap: { [key in TopPhotoType]: new () => Photo } = {
'landscape': Landscape,
'portrait': Portrait,
'underwater': UnderWater
}
export class Album {
id: number;
name: string;
topPhotoType: TopPhotoType;
@Transform(
({ value, obj }) => {
const specificClass = topPhotoTypeMap[obj.topPhotoType];
return plainToInstance(specificClass, value);
},
{
toClassOnly: true
}
)
@Type(({ object }) => topPhotoTypeMap[object?.topPhotoType])
@ValidateNested()
topPhoto: Landscape | Portrait | UnderWater;
}
let album = plainToClass(Album, albumJson);
Description
I truly appreciate the possibility to have pseudo dynamic class in my models. Unfortunately, it's not always possible to add a new specific property to make the lookup working and moreover quite often the discriminator can already be found in the parent object.
Proposed solution
Relates to :
737
582
552
510