Reputation: 328
Is there a way to solve massive decorator use inside classes?
Here's an example of a single property of a class in my NestJS app, with an incomplete swagger documentation decorator:
@ApiModelProperty({
description: 'description',
})
@Expose()
@MaxLength(100, { message: 'message' })
@IsString({ message: 'message' })
@ValidateIf(address=> address.id !== null)
@NotEquals(undefined, { message: 'message' })
address: string;
This gets huge and ugly in no time. Any way to make the code look cleaner, defining the decorators in another file, maybe?
Upvotes: 4
Views: 1399
Reputation: 5066
This good nestjs util helped in my case, maybe it helps you:
import { applyDecorators } from '@nestjs/common';
expose function ComposedDecorator(options: any) {
return applyDecorators(
Decorator1(),
Decorator2(),
AnotherDecoratorYouWant(),
)
}
And then:
@ComposedDecorator(options)
// methodOrClassOrProperty
Upvotes: 1
Reputation: 26
Not really sure for how long this has existed under nestjs/common library, but I stumbled with this issue and in case someone else stumbles with this. After requesting help on their official discord, jmcdo29 suggested https://docs.nestjs.com/custom-decorators#decorator-composition which seems like the way to go.
Upvotes: 1
Reputation: 1275
Decorators are regular typescript functions. You can try to compose multiple decorators into a single one. For exemple, you could mix the validation ones into a single decorator, like this:
function apiStringField(maxLength: number, message: string, description?: string) {
return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
ApiModelProperty()(target, propertyKey, descriptor)
Expose()(target, propertyKey, descriptor)
MaxLength(maxLength, { message })(target, propertyKey, descriptor)
IsString({ message })(target, propertyKey, descriptor)
NotEquals(undefined, { message })(target, propertyKey, descriptor)
}
}
And, use it like this (after importing it):
@apiStringField(100, 'message', 'description')
address: string;
Upvotes: 9