5

I'm confused about the mapped types in NestJS.

The documentation says that PartialType create a new class making its validation decorators optional.

So, we use it in our validation pipes as we do with the original classes.

I'm wondering if it's the normal usage of the derived classes. I mean, to make it easy to create a partial update DTO.

And if so, why is it in a swagger package (or graphql) and not in a utils of the core?

jbdemonte
  • 667
  • 1
  • 7
  • 15

1 Answers1

9

So, there's three mapped-types in Nest actually: the base @nestjs/mapped-types, the one in @nestjs/swagger, and the one in @nestjs/graphql. The reason for these packages is to allow devs to define a base class, and then be able to define classes that extend off this base class but use different decorators for validations/schema definitions. These mixin methods become useful because they read the existing metadata on the class and make modifications to it for the resulting class, like making every property optional, or leaving out key properties, like a password field on a User class.

The @nestjs/mapped-types package deals with class-validator and class-transformer metadata and is the basis for the other two packages. If the metadata doesn't exist, nothing is effected in terms of metadata, and the types are the only thing updated.

@nestjs/swagger's mapped-types update the swagger schema metadata so that your OpenAPI spec shows up properly.

Similarly, the @nestjs/graphql mapped-types updates the GraphQL schema so that Apollo doesn't throw exceptions on partial updates.

Because all of this metadata is handled differently, and it doesn't overlap, is the reason for three different ways to deal with it. Also, to help keep the base package small, rather than requiring the metadata keys from the other two packages.

Jay McDoniel
  • 57,339
  • 7
  • 135
  • 147
  • 1
    Thanks Jay, I really didnt find this information elsewhere. – Maor Barazani Nov 23 '21 at 15:42
  • Hi Jay, thanks for info. But how do I use both PartialType from @nestjs/mapped-types and @nestjs/swagger in one definition? Or do I have to create 2 different class. If create 2 different class is the only way then do I have to add the Partial class that use @nestjs/swagger to extraModels, for it to show up properly? – Man Nguyen Jan 05 '22 at 17:17
  • Why do you need both `@nestjs/swagger`'s mapped types and `@nestjs/mapped-types`' mapped types? – Jay McDoniel Jan 05 '22 at 18:02
  • if I use @nestjs/mapped-types then my OpenApi docs is doom and if I use @nestjs/swagger then my class-transform wont work. I mean I can just define my PartialDto with all the fields but optional, just thought if I could use both PartialType from both lib then it would improve my dev experience – Man Nguyen Jan 05 '22 at 19:07
  • 1
    `@nestjs/swagger`'s mapped types build _on top of_ the original `@nestjs/mapped-types`, so I don't see why your class-transformer config won't keep working – Jay McDoniel Jan 05 '22 at 19:45
  • 1
    I have a ```@Type(() -> Date)``` on one of the attribute and nestjs keep throwing me errors but if i use PartialType from ```@nestjs/mapped-types``` then it works just fine – Man Nguyen Jan 06 '22 at 14:35
  • @JayMcDoniel I have the same issue actually, using `@nestjs/mapped-types` works but does not get picked by my openapi, `@nestjs/swagger` makes openapi correct but does not pick transformers correctly. – Ali Elkhateeb Aug 03 '23 at 07:13
  • @ManNguyen did you find a workaround for this? – Ali Elkhateeb Aug 03 '23 at 07:13