typescript 使用类验证器的高级条件(可能)?

fxnxkyjh  于 2023-05-30  发布在  TypeScript
关注(0)|答案(4)|浏览(172)

TypeScript NestJS项目
我需要验证传入的DTO到我的API。它可以被描述为“创建项目”,其中我们有建筑类型(房屋,公寓,花园),并根据该类型,我们需要定义:

  • 房屋:包括客房的楼层
  • 公寓:客房
  • 花园:没有(它是一个“房间”)

房屋类型示例:

{
  type: HOUSE,
  floors: [
    {
      name: "1st floor",
      rooms: [
        {
          name: "bedroom"
        }
      ]
    }
  ]
}

扁平类型示例:

{
  type: FLAT,
  rooms: [
    {
      name: "bedroom"
    }
  ]
}

过去我是在AJV的帮助下完成的,但是现在我们迁移到NestJS,我们开始使用class-validator
我的问题是,如果我能使这些高级条件句(例如。当类型为FLAT时,class-validator中仅预期ROOMS,而非FLOORS)?

wgx48brx

wgx48brx1#

使用class-validator,您可以选择条件验证和组验证,或者您可以始终创建自定义管道并使用AJV。对于条件验证,您可以创建基于type的验证,然后让class-validator处理其余的工作

rggaifut

rggaifut2#

您必须为此创建一个自定义验证器。文档非常好:https://github.com/typestack/class-validator#custom-validation-classes
当您创建自定义验证器类时,在validate的实现中,您可以访问在args参数中验证的其他参数。只需编写if语句,如果不满足则返回false。您甚至可以返回自定义错误消息并实现自己的装饰器。

ui7jx7zq

ui7jx7zq3#

我也有类似的要求。如果您可以将传入的对象嵌套一层,那么下面的模式应该可以工作。

import { ValidateNested, IsNotEmptyObject } from 'class-validator';
import { Type } from 'class-transformer';

class MyRequestDto {
  @IsNotEmptyObject()
  @ValidateNested()
  @Type(null, {
    keepDiscriminatorProperty: true,
    discriminator: {
      property: 'type',
      subTypes: [
        {
          name: 'Flat',
          value: Flat,
        },
        {
          name: 'Room',
          value: Room,
        },
        {
          name: 'Garden',
          value: Garden,
        },
      ],
    },
  })
  entity: Flat | Room | Garden;
}

我们可以使用class-transformer提供的Type装饰器,并传入discriminator选项,该选项接受propertysubTypes属性。

  • property是用于建立传入对象的传入类型的propertyName。
  • subTypes将具有用于验证的属性和类(value)的相应值(name)。

接口定义为here

w1e3prcc

w1e3prcc4#

我对nasted对象使用这种验证:

export class PredefinedProductsDao {

  @IsEnum(ProductEnum)
  product: ProductEnum;

  @IsObject()
  @ValidateNested()
  @Type((type: TypeHelpOptions | undefined) => {
    if (type?.object) {
      const predefinedProductsDao: PredefinedProductsDao =
        type.object as PredefinedProductsDao;
      switch (predefinedProductsDao.editor) {
        case ProductEnum.FIRST:
          return FirstProductDao;
        case ProductEnum.SECOND:
          return SecondProductDao;
      }
    }
    return FirstProductDao;
  })
  predefinedConfig: FirstProductDao | SecondProductDao;
}

在我的例子中,我希望验证predefinedConfig是DAO之一,每个产品都不同。它就像雪一样工作

相关问题