question: Use `strategy: 'excludeAll'` with some explicitly untyped data
I was trying to... Almost all of my code is typed properly, with DTOs and validation on input data. All my responses are either mapped to entities (from TypeORM), or DTOs which I explicitly convert to these DTOs before returning them as plain objects again, to prevent fields that I don't want public from leaking out.
Now I'm dealing with some data which I'm not able to build the typing for, as it is calling an external API and passing through the response. I want to return this data anyway.
The problem: https://stackblitz.com/edit/typescript-playground-ec9vct?file=index.ts
In the code above, you can see that the object in both stages is just an empty object. How can I have class transformer accept that this is untyped data?
Hello @Cyberuben,
it seems that when excludeAll strategy is used, the value does not contain the nested object for some reason. This might be a bug, I have to look at this a bit if I have time.
But to answer your question. You can use the following transform @Transform(({key, obj}) => obj[key]).
Hope this helps :)
@Cyberuben This worked for me:
class MyClass {
@Expose()
@Transform(transfromExposeAll())
foo: any;
public constructor(foo: any) {
this.foo = foo;
}
}
/** Exposes all nested objects when strategy is set to `excludeAll` */
export const transfromExposeAll = () => {
@Expose()
class ExposeAll {}
@Expose()
class ExposeAllMap extends Map<unknown, unknown> {}
@Expose()
class ExposeAllSet extends Set<unknown> {}
const transform = (source: unknown): unknown => {
if (Array.isArray(source)) {
return source.map(transform);
} else if (source instanceof Set) {
return new ExposeAllSet(Array.from(source).map(transform));
} else if (source instanceof Map) {
return new ExposeAllMap(Array.from(source.entries()).map(([key, value]) => [key, transform(value)]));
} else if (typeof source === "object" && source !== null) {
return Object.assign(
new ExposeAll(),
Object.fromEntries(Object.entries(source).map(([key, value]) => [key, transform(value)])),
);
} else {
return source;
}
};
return ({ key, obj }: Pick<TransformFnParams, "key" | "obj">) => transform((obj as Record<string, unknown>)[key]);
};