title: Validate nested DTO objects using class validator
body: <p>I'm trying to use class validator in order to validate incoming data. The data consists of an array of object. Each object should be validated.</p>
  <p>The problem that I am facing is that I keep on getting errors when everything is being input correctly. It seems that the parent class is being checked with it's children's properties and so <code>whitelistValidation</code> error is being thrown for each property of the child.</p>
  <p>This is the error that is being generated:</p>
  <pre><code>[
     {
        &quot;target&quot;:{
           &quot;drainPoints&quot;:[
              {
                 &quot;drainPointType&quot;:&quot;roundsurface&quot;,
                 &quot;flowType&quot;:&quot;normal&quot;,
                 &quot;flowCoefficient&quot;:0.5,
                 &quot;point&quot;:{
                    &quot;x&quot;:0,
                    &quot;y&quot;:0
                 }
              }
           ]
        },
        &quot;value&quot;:[
           {
              &quot;drainPointType&quot;:&quot;roundsurface&quot;,
              &quot;flowType&quot;:&quot;normal&quot;,
              &quot;flowCoefficient&quot;:0.5,
              &quot;point&quot;:{
                 &quot;x&quot;:0,
                 &quot;y&quot;:0
              }
           }
        ],
        &quot;property&quot;:&quot;drainPoints&quot;,
        &quot;children&quot;:[
           {
              &quot;target&quot;:[
                 {
                    &quot;drainPointType&quot;:&quot;roundsurface&quot;,
                    &quot;flowType&quot;:&quot;normal&quot;,
                    &quot;flowCoefficient&quot;:0.5,
                    &quot;point&quot;:{
                       &quot;x&quot;:0,
                       &quot;y&quot;:0
                    }
                 }
              ],
              &quot;value&quot;:{
                 &quot;drainPointType&quot;:&quot;roundsurface&quot;,
                 &quot;flowType&quot;:&quot;normal&quot;,
                 &quot;flowCoefficient&quot;:0.5,
                 &quot;point&quot;:{
                    &quot;x&quot;:0,
                    &quot;y&quot;:0
                 }
              },
              &quot;property&quot;:&quot;0&quot;,
              &quot;children&quot;:[
                 {
                    &quot;target&quot;:{
                       &quot;drainPointType&quot;:&quot;roundsurface&quot;,
                       &quot;flowType&quot;:&quot;normal&quot;,
                       &quot;flowCoefficient&quot;:0.5,
                       &quot;point&quot;:{
                          &quot;x&quot;:0,
                          &quot;y&quot;:0
                       }
                    },
                    &quot;value&quot;:&quot;roundsurface&quot;,
                    &quot;property&quot;:&quot;drainPointType&quot;,
                    &quot;constraints&quot;:{
                       &quot;whitelistValidation&quot;:&quot;property drainPointType should not exist&quot;
                    }
                 },
                 {
                    &quot;target&quot;:{
                       &quot;drainPointType&quot;:&quot;roundsurface&quot;,
                       &quot;flowType&quot;:&quot;normal&quot;,
                       &quot;flowCoefficient&quot;:0.5,
                       &quot;point&quot;:{
                          &quot;x&quot;:0,
                          &quot;y&quot;:0
                       }
                    },
                    &quot;value&quot;:&quot;normal&quot;,
                    &quot;property&quot;:&quot;flowType&quot;,
                    &quot;constraints&quot;:{
                       &quot;whitelistValidation&quot;:&quot;property flowType should not exist&quot;
                    }
                 },
                 {
                    &quot;target&quot;:{
                       &quot;drainPointType&quot;:&quot;roundsurface&quot;,
                       &quot;flowType&quot;:&quot;normal&quot;,
                       &quot;flowCoefficient&quot;:0.5,
                       &quot;point&quot;:{
                          &quot;x&quot;:0,
                          &quot;y&quot;:0
                       }
                    },
                    &quot;value&quot;:0.5,
                    &quot;property&quot;:&quot;flowCoefficient&quot;,
                    &quot;constraints&quot;:{
                       &quot;whitelistValidation&quot;:&quot;property flowCoefficient should not exist&quot;
                    }
                 },
                 {
                    &quot;target&quot;:{
                       &quot;drainPointType&quot;:&quot;roundsurface&quot;,
                       &quot;flowType&quot;:&quot;normal&quot;,
                       &quot;flowCoefficient&quot;:0.5,
                       &quot;point&quot;:{
                          &quot;x&quot;:0,
                          &quot;y&quot;:0
                       }
                    },
                    &quot;value&quot;:{
                       &quot;x&quot;:0,
                       &quot;y&quot;:0
                    },
                    &quot;property&quot;:&quot;point&quot;,
                    &quot;constraints&quot;:{
                       &quot;whitelistValidation&quot;:&quot;property point should not exist&quot;
                    }
                 }
              ]
           }
        ]
     }
  ]
  </code></pre>
  <p>The DTO object that contains the array:</p>
  <pre><code>export class CreateDrainPointDTO extends DTO {
    @IsArray()
    @IsNotEmpty()
    @ArrayMinSize(1)
    @ValidateNested({ each: true })
    @Type(() =&gt; DrainPointDTO)
      drainPoints: DrainPoint[]
  }
  </code></pre>
  <p>The Object itself:</p>
  <pre><code>export class DrainPointDTO {
    @IsString()
    @IsOptional()
      uuid: string
  
    @IsEnum(DrainPointType)
    @IsNotEmpty()
      drainPointType: DrainPointType
  
    @IsEnum(DrainPointflowType)
    @IsNotEmpty()
      flowType: DrainPointflowType
  
    @IsArray()
    @IsNotEmpty()
     point: Point
  
    @IsNumber()
    @IsOptional()
      flowCoefficient: number
  }
  </code></pre>
  <p>My custom DTO abstract class:</p>
  <pre><code>export abstract class DTO {
    static async factory&lt;T extends DTO&gt;(Class: new () =&gt; T, partial: Partial&lt;T&gt;): Promise&lt;T&gt; {
      const dto = Object.assign(new Class(), partial)
  
      const errors = await validate(dto, { whitelist: true, forbidNonWhitelisted: true })
  
      if (errors.length &gt; 0) {
        throw new CustomError()
          .withError('invalid_parameters')
          .withValidationErrors(errors)
      }
  
      return dto
    }
  }
  </code></pre>
  <p>I use this DTO abstract class in order to have a clean way of checking the body inside the controller:</p>
  <pre><code>  async createDrainPoint (req: Request, res: Response): Promise&lt;void&gt; {
      const dto = await DTO.factory(CreateDrainPointDTO, req.body as Partial&lt;CreateDrainPointDTO&gt;)
  
      const drainPoints = await this.drainPointService.create(dto)
  
      res.status(201).json(DrainPointTransformer.array(drainPoints))
    }
  </code></pre>