NestJS集成Swagger时DTO无法正确渲染的问题排查
问题分析:Swagger文档加载时出现"_swagger is not defined"错误
问题场景
在NestJS项目中通过继承DTO复用公共属性,代码运行无异常,但访问Swagger文档时控制台报错:
Uncaught ReferenceError: _swagger is not defined
错误指向GameBrandListsDto的examples配置环节,相关代码如下:
base-brand.dto.ts
import { ApiProperty } from '@nestjs/swagger'; export class BaseBrandDto { @ApiProperty({ type: Number, required: true, example: 1, }) readonly id: number; @ApiProperty({ type: String, required: true, example: 'Default', }) readonly name: string; }
game-brand.dto.ts
import { ApiProperty, PickType } from '@nestjs/swagger'; import { BaseBrandDto } from './base/base-brand.dto'; export class GameBrandDto extends PickType(BaseBrandDto, ['id', 'name'] as const) { @ApiProperty({ example: 'EA', }) readonly name: string; }
find-all-game-brands.dto.ts
import { ApiProperty, PickType } from '@nestjs/swagger'; import { ValidateNested } from 'class-validator'; import { Type } from 'class-transformer'; import { GameBrandDto } from './game-brand.dto.ts'; class GameBrandListsDto { @ValidateNested({ each : true }) @Type(() => GameBrandDto) @ApiProperty({ type: [GameBrandDto], required: true, examples: [GameBrandDto], }) readonly lists: GameBrandDto[]; } export class FindAllGameBrandsDto extends PickType(BaseResponseDto, ['result', 'message'] as const) { @ValidatedNested({ each : true }) @Type(() => GameBrandListsDto) @ApiProperty({ type: GameBrandListsDto, required: true, example: GameBrandListsDto, }) readonly brand: GameBrandListsDto; }
错误原因
examples/example字段传入类引用而非实际示例数据:Swagger的@ApiProperty中,examples(数组示例)和example(单个示例)需要传入具体的JSON对象/数组,而不是DTO类本身。直接传入[GameBrandDto]和GameBrandListsDto会导致Swagger无法解析,生成文档时触发未定义的_swagger变量错误。- 装饰器拼写错误:
FindAllGameBrandsDto中使用了错误的@ValidatedNested装饰器,正确的应该是@ValidateNested(少了字母t),这个错误会干扰Swagger的元数据解析流程,加重异常。
修正方案
将examples和example替换为具体的示例数据,同时修正装饰器拼写:
// 修正后的find-all-game-brands.dto.ts import { ApiProperty, PickType } from '@nestjs/swagger'; import { ValidateNested } from 'class-validator'; import { Type } from 'class-transformer'; import { GameBrandDto } from './game-brand.dto'; class GameBrandListsDto { @ValidateNested({ each : true }) @Type(() => GameBrandDto) @ApiProperty({ type: [GameBrandDto], required: true, // 替换为具体的示例数组 examples: [{ id: 1, name: 'EA' }, { id: 2, name: 'Ubisoft' }], }) readonly lists: GameBrandDto[]; } export class FindAllGameBrandsDto extends PickType(BaseResponseDto, ['result', 'message'] as const) { // 修正装饰器拼写 @ValidateNested({ each : true }) @Type(() => GameBrandListsDto) @ApiProperty({ type: GameBrandListsDto, required: true, // 替换为具体的示例对象 example: { lists: [{ id: 1, name: 'EA' }], }, }) readonly brand: GameBrandListsDto; }
内容的提问来源于stack exchange,提问作者Minwoo Kim
相关产品推荐
相关产品推荐

