Description
Is there an existing issue for this?
- I have searched the existing issues
Current behavior
I'm working on setting up a validation inheritance chain between UpdateDto, CreateDto, and BaseDto for my request payloads.
I recently migrated from NestJS v8 to v11.
This code used to work in v8, but that's not the main point now. What I'd really like is a more robust and reliable approach for validating complex, related types across inherited DTOs.
Sure, I could re-write all my DTOs from scratch—but I'm mid-migration, and I suspect some behavior might have changed in newer versions, which would be completely fair.
So ideally, I’m looking for:
- A better pattern or example to handle validation cleanly across inherited DTOs.
- An explanation of any known differences in validation behavior (e.g., with PartialType, PickType, OmitType, etc.) between NestJS versions.
- A way to avoid having validations silently overridden or skipped in child classes.
First, the initial code (check the gists for unit testing):
export class Base {
@IsString()
@Length(2, 100)
subject?: string;
}
export class Create extends Base {
@IsNotEmpty()
subject: string;
}
export class UpdatePartialType extends PartialType(Create) {}
export class UpdatePartialWithPickType extends IntersectionType(
PartialType(Create),
PickType(Create, ['subject']),
) {}
export class UpdatePartialWithOmitType extends IntersectionType(
OmitType(PartialType(Create), ['subject']),
PickType(Create, ['subject']),
) {}
- Create: when there is a new object (new Create()), it validates the "not empty" decorator. But it fails validating string and length from Base.
- UpdatePartialType: it works fine when the object is "empty" (just new). But, Base validations were missing
- UpdatePartialWithPickType: when the object is new, IMO it should fail. But it doesn't. Neither it has the Base validations.
- UpdatePartialWithOmitType: better here, when the object is new, subject fails (not empty). But it continues skipping Base validations.
I have a lot of DTOs chains like these. I have detected just one, but I imagine there are others and, the lack of good testing, it might be a nightmare for next weeks.
The issue are:
- How could I force
UpdatePartial*
classes to have all the validations in the chain. - Are there a config to force that? its a problem of typescript? new behavior of decorators?
The code has some tests to visualize these inconvenientes or misunderstandings from my side.
Moreover, I've opened a question issue on class-validator here: typestack/class-validator#2608
Minimum reproduction code
https://gist.github.com/JonathanLoscalzo/c6b4e804230b3231e1a9dc8fb32c1d9c
Steps to reproduce
- create an empty nest project
- copy the gists
- run the tests
Expected behavior
- Validation on fields should be chained during inheritance, instead of overwritten
- If it can't be solved or is a new behavior, leave a comment or an info section describing the situation
Package version
@nestjs/mapped-types@2.1.0, @nestjs/*@11.0.7
Node.js version
v22.15.0
In which operating systems have you tested?
- macOS
- Windows
- Linux
Other
No response