MichalLytek / class-transformer-validator

A simple plugin for class-transformer and class-validator which combines them in a nice and programmer-friendly API.
MIT License
200 stars 19 forks source link

Make it work with optionals? #42

Closed CaffeineDuck closed 1 year ago

CaffeineDuck commented 2 years ago

How do I make it work with optional attributes? The validator is checking it regardless of the attribute being optional.

export class CreateEventDto {
  @IsString()
  @Length(5, 255)
  title: string;

  @IsString()
  @Length(5, 255)
  location: string;

  @IsString()
  @IsNotEmpty()
  @Length(5, 255)
  description: string;

  @IsUrl()
  url?: string;

  @IsString({ each: true })
  images: string[];

  @IsDateString()
  startDate: Date;

  @IsDateString()
  endDate: Date;
}

export class UpdateEventDto implements Partial<CreateEventDto> {}

Error when I run try to validate UpdateEventDto body:

{
            "target": {
                "name": "AuraEd workshop on web automation with python"
            },
            "property": "title",
            "children": [],
            "constraints": {
                "length": "title must be longer than or equal to 5 characters",
                "isString": "title must be a string"
            }
        },
        {
            "target": {
                "name": "AuraEd workshop on web automation with python"
            },
            "property": "location",
            "children": [],
            "constraints": {
                "length": "location must be longer than or equal to 5 characters",
                "isString": "location must be a string"
            }
        },
        {
            "target": {
                "name": "AuraEd workshop on web automation with python"
            },
            "property": "description",
            "children": [],
            "constraints": {
                "length": "description must be longer than or equal to 5 characters",
                "isNotEmpty": "description should not be empty",
                "isString": "description must be a string"
            }
        },
        {
            "target": {
                "name": "AuraEd workshop on web automation with python"
            },
            "property": "url",
            "children": [],
            "constraints": {
                "isUrl": "url must be an URL address"
            }
        },
        {
            "target": {
                "name": "AuraEd workshop on web automation with python"
            },
            "property": "startDate",
            "children": [],
            "constraints": {
                "isDateString": "startDate must be a ISOString"
            }
        },
        {
            "target": {
                "name": "AuraEd workshop on web automation with python"
            },
            "property": "endDate",
            "children": [],
            "constraints": {
                "isDateString": "endDate must be a ISOString"
            }
        }

The API Input:

{
    "name": "AuraEd workshop on web automation with python"
}
dieeisenefaust commented 1 year ago

Partial<...> is a Typescript option, so it will generate a new class with all attributes set to optional as indicated with a "?" (like title?: string).

However, class-validator does not use that Typescript "?" to determine whether an attribute is optional; you have to use the @IsOptional() decorator to indicate this, which is not generated by Partial/'?' from the core Typescript functionality.