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.

Sua interface
// Your existing interface (no need to convert to a class)
export interface RegisterResponseDto {
  success: boolean;
  message: string | null;
}

Generated output:

Generated
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
// 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:

ts
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
Preserving existing annotations

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
// users.controller.ts
@Post('logout')
@HttpCode(204)
logout(): void { ... }

Generated output:

ts
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.