javascriptnestjsdto

nest js dto allow array of string and only string


I have a DTO like this and I'm trying to allow string and array and validate if it is string or array.

export class MyRequestDto extends SomeBaseRequestDto {
  @IsOptional()
  @IsString()
  key?: string;
}

When I request this http://localhost:3000/path?key=123asd, it works. But, When I try to make this request http://localhost:3000/path?key=123asd&key=321asd, it doesn't work and sends the error "alias must be a string"

when I try something like this it works perfectly,

export class MyRequestDto extends SomeBaseRequestDto {
  @IsOptional()
  key?: string | string[];
}

I don't want to do that because I need to validate if it is an array or a string. Do you know how I can do that?

I tried to change the DTO in these ways,

  @IsOptional()
  @IsArray()
  @IsString({ each: true, message: "Each item should be string" })

and,

  @IsOptional()
  @IsArray()
  @IsString()

and,

  @IsOptional()
  @IsString()
  @IsArray()

and,

  @IsOptional()

Solution

  • To achieve this you have to create a Custom Validation.

    Similar Question: How can my class-validator validate union string | number?

    @ValidatorConstraint({ name: 'string-or-array', async: false })
    export class IsStringOrArray implements ValidatorConstraintInterface {
    
      validate(input: any, args: ValidationArguments) {
        return typeof input === 'string' || Array.isArray(input);
      }
    
      defaultMessage(args: ValidationArguments) {
        return '($value) must be string or array';
      }
    }
    
    

    Then you have to use it like,

    export class MyRequestDto extends SomeBaseRequestDto {
      @IsOptional()
      @Validate(IsStringOrArray)
      key?: string | string[];
    }