You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过@nestjs/swagger正确定义数组的数组返回类型并复用DTO?

解决NestJS Swagger描述数组的数组(元组类型)的问题

针对你遇到的类型不匹配和Swagger展示错误问题,核心原因是用类模拟数组/元组的思路本身存在类型不兼容——类本质是对象类型,而你需要的是数组(元组)类型。下面给出可行的解决方案:

1. 核心思路

放弃用类DTO模拟数组/元组,直接使用TypeScript类型别名定义返回结构,同时在Swagger的响应装饰器中手动配置OpenAPI Schema,精准描述嵌套数组和元组的结构。

2. 针对简单示例的解决代码

对于你给出的RealApiReturnType = [string[], string]类型,修改后的代码如下:

import { Controller, Get } from '@nestjs/common';
import { ApiOkResponse } from '@nestjs/swagger';

// 复用的类型别名
type RealApiReturnType = [string[], string];

@Controller()
export class AppController {
  @Get()
  @ApiOkResponse({
    schema: {
      type: 'array',
      // 定义元组的两个元素结构
      items: [
        { type: 'array', items: { type: 'string' } }, // 第一个元素:字符串数组
        { type: 'string' } // 第二个元素:字符串
      ],
      // 限制数组长度为2,符合元组特性
      minItems: 2,
      maxItems: 2
    }
  })
  getHello(): RealApiReturnType {
    // 类型完全匹配,无需断言
    return [['Bad', 'Design'], 'I know'];
  }
}

3. 针对复杂实际类型IrlDto的解决代码

对于你的复杂只读元组类型,我们可以逐层定义Swagger Schema,同时保留TypeScript的类型检查:

import { Controller, Get } from '@nestjs/common';
import { ApiOkResponse } from '@nestjs/swagger';

// 复用的实际业务类型
export type IrlDto = readonly [
  readonly (readonly [`${string}:${string}`, string, `${number}`, number])[],
  readonly ['COLUMN', 'ROW', 'ID', 'AVAILABLE'],
];

// 抽离可复用的Swagger Schema常量
const IrlDtoSchema = {
  type: 'array',
  // 最外层是长度为2的元组
  items: [
    {
      type: 'array',
      // 第一个元素:元组数组,每个元组包含4个固定类型元素
      items: {
        type: 'array',
        items: [
          { type: 'string', pattern: '^.+:.+$' }, // 匹配 `${string}:${string}` 格式
          { type: 'string' },
          { type: 'string', pattern: '^\\d+$' }, // 匹配 `${number}` 格式
          { type: 'number' }
        ],
        minItems: 4,
        maxItems: 4 // 限制元组长度为4
      }
    },
    {
      type: 'array',
      // 第二个元素:固定值的字符串元组
      items: [
        { type: 'string', enum: ['COLUMN'] },
        { type: 'string', enum: ['ROW'] },
        { type: 'string', enum: ['ID'] },
        { type: 'string', enum: ['AVAILABLE'] }
      ],
      minItems: 4,
      maxItems: 4 // 限制元组长度为4
    }
  ],
  minItems: 2,
  maxItems: 2 // 限制最外层元组长度为2
};

@Controller()
export class AppController {
  @Get('complex')
  @ApiOkResponse({ schema: IrlDtoSchema })
  getComplex(): IrlDto {
    // 类型完全匹配,直接返回
    return [
      [['a:b', 'test', '123', 456]],
      ['COLUMN', 'ROW', 'ID', 'AVAILABLE']
    ];
  }
}

4. 关键说明

  • 类型兼容性:使用TypeScript类型别名直接作为返回类型,避免了类与数组类型的不匹配问题,代码无需类型断言即可通过类型检查。
  • Swagger展示准确性:通过手动配置schema,明确描述每个层级的数组/元组结构,用minItems和maxItems模拟元组的固定长度特性,同时可以添加pattern、enum等约束来匹配业务类型的格式要求。
  • 复用性:将Swagger Schema抽离为常量后,可以在多个接口中复用,同时TypeScript类型别名也能在代码的其他地方复用。

内容的提问来源于stack exchange,提问作者uPaymeiFixit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 14:55:57