Description
I have a class that has three properties: "type", "data" and "metadata". Based on the value of "type" I am transforming "data" and "metadata" to different classes. I am using the @Type
decorator with a function that returns different classes with a switch-case on "type" (I don't think I can use a normal discriminator because the "type" property is not inside "data" or "metadata", and I can't use @type
on the whole class). I want to skip transformation on "data" or "metadata" when "type" is equal to some value. I want the property to be in the transformed class as a plain object (mostly for logging purposes, I'll just dump the value into the log).
import { Type } from "class-transformer";
class AMetadata {
foo!: string;
}
class BMetadata {
bar!: number;
}
class AData {
foobar!: string;
}
class CData {
banana!: string;
}
const TYPES = ["a", "b", "c"] as const;
type TType = typeof TYPES[number];
export class EventSchema {
type!: TType;
@Type(options => {
if (!options || !options.object) return unknown;
switch (options.object.type as TType) {
case "a":
return AMetadata;
case "b":
return BMetadata;
case "c":
return unknown;
}
})
metadata!: AMetadata | BMetadata | unknown;
@Type(options => {
if (!options || !options.object) return unknown;
switch (options.object.type as TType) {
case "a":
return AData;
case "b":
return unknown;
case "c":
return CData;
}
})
data!: AData | CData | unknown;
}
The problem:
I don't know of a way to return an "unknown" value in the @Type
decorator callback. The callback only returns a Function
and when trying to return something like (value: unknown) => value
I got the error "Cannot read properties of undefined (reading 'constructor')", which probably means it only accepts classes. I want to support any value (string, boolean, number, Record<string, unknown>), but I could not find a way to achieve this.