Skip to content

Validation issues during overriding fields #1697

Open
@JonathanLoscalzo

Description

@JonathanLoscalzo

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

  1. create an empty nest project
  2. copy the gists
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions