typescript 如何使用类验证器验证多个类型的嵌套数组?

2wnc66cl  于 2023-03-31  发布在  TypeScript
关注(0)|答案(1)|浏览(142)

我使用nestjs和class-validator,我有以下情况:

  • 两个具有相同字段名称但具有不同类型的类:
class A {
  @IsDefined()
  field: number;
}

class B {
  @IsDefined()
  field: string;
}
  • 第三个类包含A或B类型的元素数组,我的问题是如何根据自己的类验证每个数组成员:
class C {
  @ValidateNested({ each: true })
  @Type(I_DON'T_KNOW_WHAT_TO_DO_HERE)
  array: (A | B)[];
}

如何验证阵列?
先谢了!

5n0oy7gb

5n0oy7gb1#

你应该有一个描述性的字段,以允许类转换器识别要转换的类型,并在验证中使用。
在下面的例子中,如果属性"version"等于“v1,"则field应该是number,另一方面,如果属性version等于“v2,”则属性field应该是string .
discriminator属性中,您应该设置一个字段,用于标识嵌套对象的不同多态形式。subTypes.[].value是用于验证的类,subTypes.[].namediscriminator字段应该具有的值,以假定subTypes.[].name字段中添加的类。

import { Type } from 'class-transformer';
import { IsDefined, IsEnum, IsNumber, IsString, ValidateNested } from 'class-validator';

enum VersionEnum {
  VERSION_1 = 'v1',
  VERSION_2 = 'v2',
}

class Discriminator {
  @IsEnum(VersionEnum)
  version: VersionEnum;
}

class A extends Discriminator {
  @IsDefined()
  @IsNumber()
  field: number;
}

class B extends Discriminator {
  @IsDefined()
  @IsString()
  field: string;
}

export class C {
  @ValidateNested({ each: true })
  @Type(() => Discriminator, {
    discriminator: {
      property: 'version',
      subTypes: [
        { value: A, name: VersionEnum.VERSION_1 },
        { value: B, name: VersionEnum.VERSION_2 },
      ],
    },
    keepDiscriminatorProperty: true,
  })
  array: (A | B)[];
}

现在你的控制器应该看起来像这样:

@Controller()
export class AppController {
  @Post()
  public example(
    @Body(new ValidationPipe({ transform: true }))
    body: C,
  ) {
    return body;
  }
}

你可以做你的请求:

curl --location 'localhost:3000/' \
--header 'Content-Type: application/json' \
--data '{
  "array": [
    {
      "version": "v1",
      "field": 1
    },
    {
      "version": "v2",
      "field": "2"
    }
  ]
}'

如果将嵌套数组的第二个元素更改为version属性为“v2”的数字,则会看到错误:
一个三个三个一个
参考文献:https://github.com/typestack/class-transformer#providing-more-than-one-type-option

相关问题