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()
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[];
}