2 回答
TA贡献1834条经验 获得超8个赞
泛型通常是仅编译时功能。除非您有某种方式发出元数据,包括泛型(不确定这是否容易实现)。
如果需要在运行时使用类型,通常应该将其作为常规参数传递,因此在这种情况下,必须更改签名以适应这一点:
@IsUnique(User, 'username')
这可能就是为什么在注入存储库时您通过 来执行它@InjectRepository(User),它也将实体类作为参数。我怀疑是否IsUniqueConstraint可以按原样注入存储库。您可能需要根据装饰器传递的实体类型从 DI 容器/连接管理器解析它。
根据文档,您可以直接将对象分配给validator,而不仅仅是类/构造函数,因此您可以创建验证器的具体实例,手动将解析的存储库传递给构造函数。
所以,也许是这样的:
import { getRepository } from "typeorm";
// ...
export function IsUnique(
entity: Function,
column: string,
validationOptions?: ValidationOptions) {
// Not sure if this works here. Maybe it needs to be
// moved into the returned function or a different resolution
// mechanism is required.
const repository = getRepository(entity);
return (object: object, propertyName: string) => {
registerDecorator({
target: object.constructor,
propertyName,
options: validationOptions,
constraints: [column],
validator: new IsUniqueConstraint(repository),
});
};
}
TA贡献1866条经验 获得超5个赞
好的,在尝试了很多之后,我以另一种方式解决了它。感谢@HB 向我展示了路径。
为了做同样的事情,我将实体传递给验证器并在类本身中生成存储库。因为 Nest JS 注入仅适用于类。
import { registerDecorator, ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments, ValidationOptions } from 'class-validator';
import { Injectable } from '@nestjs/common';
import { Connection } from 'typeorm';
import { InjectConnection } from '@nestjs/typeorm';
@ValidatorConstraint({ name: 'isUnique', async: true })
@Injectable()
export class IsUniqueConstraint implements ValidatorConstraintInterface {
constructor(@InjectConnection() private readonly connection: Connection) { }
async validate(value: string, args: ValidationArguments) {
const [entity, column] = args.constraints;
const repository = this.connection.getRepository(entity);
const result = await repository.findOne({ where: { [column]: value } });
if (result) {
return false;
}
return true;
}
defaultMessage(args: ValidationArguments) {
return `"${args.value}" already exists for ${args.constraints[1]}`;
}
}
export function IsUnique(entity: Function, column: string, validationOptions?: ValidationOptions) {
return (object: object, propertyName: string) => {
registerDecorator({
target: object.constructor,
propertyName,
options: validationOptions,
constraints: [entity, column],
validator: IsUniqueConstraint,
});
};
}
添加回答
举报