typestack / class-validator

Decorator-based property validation for classes.
MIT License
10.89k stars 786 forks source link

[bug] Inherited classes with nested/complex properties are not validated #1010

Open kkorus opened 3 years ago

kkorus commented 3 years ago
  "dependencies": {
    "class-transformer": "^0.4.0",
    "class-validator": "^0.13.1",
    "reflect-metadata": "^0.1.13"
  },

My model

import 'reflect-metadata';
import {
  IsBoolean,
  IsDefined,
  IsNotEmptyObject,
  ValidateNested,
  IsNumber,
  validate,
} from 'class-validator';
import { Type } from 'class-transformer';

class ChildClassProperty {
  @IsNumber()
  rx: number;
}

class Base {
  @IsBoolean()
  bar: boolean;
}

class ChildClass extends Base {
  @IsDefined()
  @IsNotEmptyObject()
  @ValidateNested()
  @Type(() => ChildClassProperty)
  data: ChildClassProperty;
}

first validation: (works): This validation works because data property should be defined

    const toValidate = new ChildClass();
    toValidate.bar = true;
    const validateResult = await validate(toValidate);
    console.log(validateResult);

second validation: (does not work): This validation does not work. I have defined data property with wrong values. validation result is []

    const toValidate = new ChildClass();
    toValidate.bar = true;
    // @ts-ignore
    toValidate.data = { rx: 'a', fooBar: '123' }; // I should not be able to assign 'a' to rx or use property fooBar
    const validateResult = await validate(toValidate);
    console.log(validateResult);
PizzaJu commented 3 years ago

I have same question

kkorus commented 3 years ago

I haven't test it but maybe plainToClass would work :thinking:

PizzaJu commented 3 years ago

I think that using '// @ts-ignore' to defined 'toValidate.data' maybe make @ValidateNested pass. Because in you code, 'toValidate.data' is a base Object.