Type inference
Three automatic mechanisms: interfaces become inline schema, class-validator becomes JSON Schema, @HttpCode() becomes the right status.
Interface-typed DTOs
When a response or body type is a TypeScript interface (not a class), Swagger can't use it as a type: value because interfaces are erased at runtime. nestjs-docfy detects this automatically and generates an inline schema: object, with no changes to your code.
// Your existing interface (no need to convert to a class)
export interface RegisterResponseDto {
success: boolean;
message: string | null;
}Generated output:
ApiResponse({
status: 201,
description: 'Created',
schema: {
type: 'object',
properties: {
success: { type: 'boolean' },
message: { type: 'string', nullable: true },
},
required: ['success'],
},
}),Supports: primitives, nullable unions (T | null), arrays, nested interfaces, and optional properties (excluded from required).
class-validator inference
When a DTO class uses class-validator decorators and doesn't already have @ApiProperty on its properties, nestjs-docfy infers a full JSON Schema from the validation decorators, with no manual annotation needed.
// create-user.dto.ts
import { IsString, IsEmail, MinLength, IsOptional } from 'class-validator';
export class CreateUserDto {
@IsString()
@MinLength(2)
name: string;
@IsEmail()
email: string;
@IsOptional()
@IsString()
bio?: string;
}Generated output:
ApiBody({
schema: {
type: 'object',
properties: {
name: { type: 'string', minLength: 2 },
email: { type: 'string', format: 'email' },
bio: { type: 'string' },
},
required: ['name', 'email'],
},
}),Supported decorators
| Decorator |
|---|
@IsString |
@IsEmail |
@IsUrl |
@IsUUID |
@IsDateString |
@IsNumber |
@IsInt |
@IsBoolean |
@IsArray |
@Min |
@Max |
@MinLength |
@MaxLength |
@IsOptional |
If any property on the class already has @ApiProperty, inference is skipped and type: ClassName is used instead; your existing Swagger annotations are never overwritten.
@HttpCode() support
NestJS's @HttpCode() decorator overrides the default HTTP status code for a route handler. nestjs-docfy reads it automatically and uses the correct code in the generated ApiResponse.
// users.controller.ts
@Post('logout')
@HttpCode(204)
logout(): void { ... }Generated output:
logout: [
ApiOperation({ summary: 'Logout' }),
ApiResponse({ status: 204, description: 'No Content' }),
],Without @HttpCode(), the default codes apply: 201 for @Post, 200 for every other HTTP verb.