打字稿装饰混乱
Posted
技术标签:
【中文标题】打字稿装饰混乱【英文标题】:Typescript decorator mess 【发布时间】:2020-01-31 03:25:50 【问题描述】:有没有办法解决类内部大量使用装饰器的问题?
这是我的 NestJS 应用程序中一个类的 single 属性的示例,带有一个不完整的 swagger 文档 装饰器:
@ApiModelProperty(
description: 'description',
)
@Expose()
@MaxLength(100, message: 'message' )
@IsString( message: 'message' )
@ValidateIf(address=> address.id !== null)
@NotEquals(undefined, message: 'message' )
address: string;
这很快就会变得巨大而丑陋。任何让代码看起来更干净的方法,在另一个文件中定义装饰器,也许?
【问题讨论】:
你能定义一下solve
的意思吗?
如果一个库决定使用装饰器,它就会使用装饰器......对此并不能做太多......也许可以定义一些复合装饰器......
@Olian04 解决我的意思是在一个文件中没有那么多装饰行,它们使代码难以阅读,并且您混合了不同类型的它们(即验证和文档)。例如,使用 express-validator 你有时会得到一个巨大的链式验证,但是由于路由器如何使用中间件,你可以将它从你的文件中删除到另一个文件中,然后将它作为一组验证中间件导入。这使得代码超级干净。但是我没有使用装饰器的经验,我想知道是否有办法获得类似的结果。
有几件事要研究一下,看看你是否可以减少你正在使用的装饰器的数量。你有一个@ValidateIf(address => address.id !== null)
,但你的address
类型是string
,它没有id 字段。 @Expose()
仅在您想公开类的字段但没有真正的验证来运行时才需要,因此有一个无关的装饰器。我很确定您可以通过@IsString()
装饰器中的选项或使用@Length()
装饰器来组合您的最大和最小长度(1,100)来摆脱@NotEquals()
。
【参考方案1】:
装饰器是常规的打字稿功能。您可以尝试将多个装饰器组合成一个。例如,您可以将验证器混合到单个装饰器中,如下所示:
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)
并且,像这样使用它(在导入之后):
@apiStringField(100, 'message', 'description')
address: string;
【讨论】:
【参考方案2】:这个好的nestjs util对我有帮助,也许对你有帮助:
import applyDecorators from '@nestjs/common';
expose function ComposedDecorator(options: any)
return applyDecorators(
Decorator1(),
Decorator2(),
AnotherDecoratorYouWant(),
)
然后:
@ComposedDecorator(options)
// methodOrClassOrProperty
【讨论】:
【参考方案3】:不确定这在 nestjs/common 库下已经存在了多久,但我偶然发现了这个问题,以防其他人遇到这个问题。在就他们的官方不和谐请求帮助后,jmcdo29 建议 https://docs.nestjs.com/custom-decorators#decorator-composition 这似乎是要走的路。
【讨论】:
以上是关于打字稿装饰混乱的主要内容,如果未能解决你的问题,请参考以下文章