NestJS使用PickType处理嵌套类属性时Swagger输出空结构问题
问题原因
- 你原始类中的
payment是内联对象类型,并非带有Swagger装饰器元数据的独立类,Swagger运行时扫描无法读取内联对象的内部字段信息,因此生成空对象。 PickType仅支持对已定义、带有Swagger元数据的类做字段筛选,无法直接处理TS索引访问类型(比如Videochat['payment']),这类类型信息编译后会消失,没有对应的运行时元数据供Swagger读取。- 嵌套使用
PickType(PickType(Videochat, ['payment']), ['status', 'type'])的写法逻辑有误:第一层PickType返回的类仅包含payment字段,外层PickType是筛选该类的顶层字段,而非筛选payment的内部字段。
解决方案
推荐方案:抽离嵌套类(可复用、易维护)
第一步先将嵌套的payment属性抽为独立的DTO类,添加必要的@ApiProperty装饰器:
import { ApiProperty } from '@nestjs/swagger'; import { PickType } from '@nestjs/swagger'; // 优先用swagger包导出的PickType,元数据更全 // 抽离嵌套的Payment类 export class Payment { @ApiProperty() status: string; @ApiProperty() type: string; } // 改造原始Product类(你的Videochat类同理修改) export class Product { @ApiProperty() status: string; @ApiProperty({ type: () => Payment }) payment: Payment; }
第二步构造你需要的目标DTO:
如果要保留payment下的所有字段,直接继承PickType即可:
export class PartialClass extends PickType(Product, ['payment']) {}
如果仅需要payment下的部分字段,对Payment类单独使用PickType:
// 筛选Payment类的指定字段 const PickedPayment = PickType(Payment, ['status', 'type']); export class PartialClass { @ApiProperty({ type: () => PickedPayment }) payment: PickedPayment; }
临时方案:硬写Schema(不推荐,复用性差)
如果不想修改原始类结构,可以直接在@ApiProperty中手动指定schema:
import { ApiProperty } from '@nestjs/swagger'; export class PartialClass { @ApiProperty({ schema: { type: 'object', properties: { status: { type: 'string' }, type: { type: 'string' } }, required: ['status', 'type'] // 按需配置是否必填 } }) payment: Pick<Product['payment'], 'type' | 'status'>; }
内容的提问来源于stack exchange,提问作者Daniel Janke
相关产品推荐
相关产品推荐

