如何在类型中传递泛型类型?

我正在尝试为 Typestack 类验证器创建一个新约束。“IsUnique”约束将实体作为类型,它的列作为参数来检查该列是否在数据库中不存在并且是唯一的。


我已经尝试了下面的代码,但不知何故我无法通过 registerDecorator 中的验证器键将类型传递给“IsUniqueConstraint”。因为,我是 Typescript 的新手,所以我不太了解它的概念。


有人可以帮我知道我们该怎么做吗?


is-unique.constraint.ts


import { registerDecorator, ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments, ValidationOptions } from 'class-validator';

import { Injectable } from '@nestjs/common';

import { Repository } from 'typeorm';


@ValidatorConstraint({ name: 'isUnique', async: true })

@Injectable()

export class IsUniqueConstraint<T> implements ValidatorConstraintInterface {


    constructor(private readonly repository: Repository<T>) { }


    async validate(value: string, args: ValidationArguments) {

        const [column] = args.constraints;


        const result = await this.repository.findOne({ where: { [column]: value } });


        if (result) {

            return false;

        }


        return true;

    }


    defaultMessage(args: ValidationArguments) {

        return `"${args.value}" already exists for ${args.constraints[0]}`;

    }


}


export function IsUnique<T>(column: string, validationOptions?: ValidationOptions) {

    return (object: object, propertyName: string) => {

        registerDecorator({

            target: object.constructor,

            propertyName,

            options: validationOptions,

            constraints: [column],

            validator: IsUniqueConstraint,

        });

    };

}


用户.dto.ts


import { IsNotEmpty } from 'class-validator';

import { IsUnique } from './../shared/constraints/is-unique.constraint';

import { User } from './user.entity';


export class CreateUserDto {

  @IsNotEmpty()

  @IsUnique<User>('username')

  readonly username: string;

}


拉莫斯之舞
浏览 281回答 2
2回答

MMMHUHU

泛型通常是仅编译时功能。除非您有某种方式发出元数据,包括泛型(不确定这是否容易实现)。如果需要在运行时使用类型,通常应该将其作为常规参数传递,因此在这种情况下,必须更改签名以适应这一点:@IsUnique(User, 'username')这可能就是为什么在注入存储库时您通过 来执行它@InjectRepository(User),它也将实体类作为参数。我怀疑是否IsUniqueConstraint可以按原样注入存储库。您可能需要根据装饰器传递的实体类型从 DI 容器/连接管理器解析它。根据文档,您可以直接将对象分配给validator,而不仅仅是类/构造函数,因此您可以创建验证器的具体实例,手动将解析的存储库传递给构造函数。所以,也许是这样的:import { getRepository } from "typeorm";// ...export function IsUnique(&nbsp; &nbsp; entity: Function,&nbsp; &nbsp; column: string,&nbsp; &nbsp; validationOptions?: ValidationOptions) {&nbsp; &nbsp; // Not sure if this works here. Maybe it needs to be&nbsp; &nbsp; // moved into the returned function or a different resolution&nbsp; &nbsp; // mechanism is required.&nbsp; &nbsp; const repository = getRepository(entity);&nbsp;&nbsp; &nbsp; return (object: object, propertyName: string) => {&nbsp; &nbsp; &nbsp; &nbsp; registerDecorator({&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; target: object.constructor,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; propertyName,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; options: validationOptions,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; constraints: [column],&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; validator: new IsUniqueConstraint(repository),&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; };}

心有法竹

好的,在尝试了很多之后,我以另一种方式解决了它。感谢@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 {&nbsp; &nbsp; constructor(@InjectConnection() private readonly connection: Connection) { }&nbsp; &nbsp; async validate(value: string, args: ValidationArguments) {&nbsp; &nbsp; &nbsp; &nbsp; const [entity, column] = args.constraints;&nbsp; &nbsp; &nbsp; &nbsp; const repository = this.connection.getRepository(entity);&nbsp; &nbsp; &nbsp; &nbsp; const result&nbsp; &nbsp; &nbsp;= await repository.findOne({ where: { [column]: value } });&nbsp; &nbsp; &nbsp; &nbsp; if (result) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; }&nbsp; &nbsp; defaultMessage(args: ValidationArguments) {&nbsp; &nbsp; &nbsp; &nbsp; return `"${args.value}" already exists for ${args.constraints[1]}`;&nbsp; &nbsp; }}export function IsUnique(entity: Function, column: string, validationOptions?: ValidationOptions) {&nbsp; &nbsp; return (object: object, propertyName: string) => {&nbsp; &nbsp; &nbsp; &nbsp; registerDecorator({&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; target: object.constructor,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; propertyName,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; options: validationOptions,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; constraints: [entity, column],&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; validator: IsUniqueConstraint,&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; };}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript