@@ -8,7 +8,7 @@ import {ValidationTypes} from "./ValidationTypes";
88import { ConstraintMetadata } from "../metadata/ConstraintMetadata" ;
99import { ValidationArguments } from "./ValidationArguments" ;
1010import { ValidationUtils } from "./ValidationUtils" ;
11- import { isPromise } from "../utils" ;
11+ import { isPromise , convertToArray } from "../utils" ;
1212
1313/**
1414 * Executes validation over given object.
@@ -225,8 +225,9 @@ export class ValidationExecutor {
225225 return metadatas
226226 . filter ( metadata => {
227227 if ( metadata . each ) {
228- if ( value instanceof Array ) {
229- return ! value . every ( ( subValue : any ) => this . validator . validateValueByMetadata ( subValue , metadata ) ) ;
228+ if ( value instanceof Array || value instanceof Set || value instanceof Map ) {
229+ const arrayValue = convertToArray ( value ) ;
230+ return ! arrayValue . every ( ( subValue : any ) => this . validator . validateValueByMetadata ( subValue , metadata ) ) ;
230231 }
231232
232233 } else {
@@ -259,7 +260,7 @@ export class ValidationExecutor {
259260 constraints : metadata . constraints
260261 } ;
261262
262- if ( ! metadata . each || ! ( value instanceof Array ) ) {
263+ if ( ! metadata . each || ! ( value instanceof Array || value instanceof Set || value instanceof Map ) ) {
263264 const validatedValue = customConstraintMetadata . instance . validate ( value , validationArguments ) ;
264265 if ( isPromise ( validatedValue ) ) {
265266 const promise = validatedValue . then ( isValid => {
@@ -279,8 +280,10 @@ export class ValidationExecutor {
279280 return ;
280281 }
281282
283+ // convert set and map into array
284+ const arrayValue = convertToArray ( value ) ;
282285 // Validation needs to be applied to each array item
283- const validatedSubValues = value . map ( ( subValue : any ) => customConstraintMetadata . instance . validate ( subValue , validationArguments ) ) ;
286+ const validatedSubValues = arrayValue . map ( ( subValue : any ) => customConstraintMetadata . instance . validate ( subValue , validationArguments ) ) ;
284287 const validationIsAsync = validatedSubValues
285288 . some ( ( validatedSubValue : boolean | Promise < boolean > ) => isPromise ( validatedSubValue ) ) ;
286289
@@ -338,33 +341,16 @@ export class ValidationExecutor {
338341
339342 const targetSchema = typeof metadata . target === "string" ? metadata . target as string : undefined ;
340343
341- if ( value instanceof Array ) {
342- value . forEach ( ( subValue : any , index : number ) => {
344+ if ( value instanceof Array || value instanceof Set || value instanceof Map ) {
345+ // Treats Set as an array - as index of Set value is value itself and it is common case to have Object as value
346+ const arrayLikeValue = value instanceof Set ? Array . from ( value ) : value ;
347+ arrayLikeValue . forEach ( ( subValue : any , index : any ) => {
343348 const validationError = this . generateValidationError ( value , subValue , index . toString ( ) ) ;
344349 errors . push ( validationError ) ;
345350
346351 this . execute ( subValue , targetSchema , validationError . children ) ;
347352 } ) ;
348353
349- } else if ( value instanceof Set ) {
350- let index = 0 ;
351- value . forEach ( ( subValue : any ) => {
352- const validationError = this . generateValidationError ( value , subValue , index . toString ( ) ) ;
353- errors . push ( validationError ) ;
354-
355- this . execute ( subValue , targetSchema , validationError . children ) ;
356-
357- ++ index ;
358- } ) ;
359-
360- } else if ( value instanceof Map ) {
361- value . forEach ( ( subValue : any , key : any ) => {
362- const validationError = this . generateValidationError ( value , subValue , key . toString ( ) ) ;
363- errors . push ( validationError ) ;
364-
365- this . execute ( subValue , targetSchema , validationError . children ) ;
366- } ) ;
367-
368354 } else if ( value instanceof Object ) {
369355 this . execute ( value , targetSchema , errors ) ;
370356
0 commit comments