Background:
I used nestjs interceptor to put returned data from controller inside data
property and add some other properties. Now I'd like to use @ApiOkResponse
that would reflect the nested properties.
Controller returns
{
prop1: 'val1',
prop2: 'val2'
}
After it was intercepted it returns
data: {
prop1: 'val1',
prop2: 'val2'
},
addedProp: 'addedVal'
I also have say two classes:
// Have many variations of similar classes (for different controllers (types of data)
class NotYetIntercepted {
@ApiProperty()
prop1: string;
@ApiProperty()
prop2: string;
}
class Intercepted<T = any> {
@ApiProperty()
data: T;
@ApiProperty()
addedProp: string;
}
Challenge
Now I'd like to add to my controllers @ApiOkResponse({ type: Intercepted })
but also somehow specify that data
property of class Intercepted
should be of type NotYetIntercepted
.
I tried creating a custom decorator like this:
import { ValidateNested } from 'class-validator';
import { ApiProperty, ApiResponseOptions, ApiOkResponse } from '@nestjs/swagger';
import { Intercepted } from '@appnamespace/models';
import { Type } from 'class-transformer';
export const CustomApiOkResponse = (notYetIntercepted: Function, options?: Omit<ApiResponseOptions, 'type'>) => {
class InterceptedWithData extends Intercepted {
@ApiProperty()
@ValidateNested()
@Type(() => notYetIntercepted)
data: typeof notYetIntercepted;
}
return ApiOkResponse({
...options,
type: InterceptedWithData,
});
};
That didn't work. When I removed @Type() => notYetIntercepted)
and set data
as data: notYetIntercepted
it sort of worked somehow (with typescript warning) but it overridden all values in my swagger docs to whatever was the last passed value to (@CustomApiOkResponse(AnotherNotYetIntercepted)
).
I know I could create a class for each nested data type but is there a cleaner solution?
Thank you for your time