Well Nestjs itself uses class-validators for DTOs,
So you can move them to an external package, there you'll be able to declare your DTOs.
After doing that you can consume the DTOs from your NestJS app and also from your React app.
For example, this is my implementation of a DTO on a package:
export const getCreateUserDto = (ApiPropertySwagger?: any) => {
// We did this to avoid having to include all nest dependencies related to ApiProperty on the client side too
// With this approach the value of this decorator will be injected by the server but wont affect the client
const ApiProperty = ApiPropertySwagger || function () {};
class CreateUserDto {
@IsEmail()
@ApiProperty({
description: "This is required and must be a valid email",
type: String,
})
email: string;
@IsString()
@MinLength(2)
@ApiProperty({
description: "This is required and must be at least 2 characters long",
type: String,
})
firstName: string;
@IsString()
@IsOptional()
lastName?: string;
@IsString()
@IsOptional()
nationality?: string;
}
return CreateUserDto;
};
In your NestJS app you can do the following:
import { ApiProperty } from '@nestjs/swagger';
// Here we send `ApiProperty` dependency to be added to`CreateUserDto`
export const _CreateUserDto = getCreateUserDto(ApiProperty);
// This allows using it as a TS type and as a constructor class
export class CreateUserDto extends _CreateUserDto {}
And in your react app you can do:
import { getCreateUserDto } from "@sample/dtos";
// We don't need `ApiProperty` on the client,
// so it will fallback on the default empty decorator
const _CreateUserDto = getCreateUserDto();
// This allows using it as a TS type and as a constructor class
class CreateUserDto extends _CreateUserDto {}
I just posted a blog with this implementation:
https://dev.to/facup3/fullstack-nestjs-dtos-for-your-web-app-4f60
I used React + react-hook-form to run same validations on the client side than in the nest controllers.