Minimum repro for the bug described in the linked issue.
// dto.ts
import { ApiProperty } from "@nestjs/swagger";
export type CellValue = string | number | null;
export class Cell {
@ApiProperty({
oneOf: [{ type: "string" }, { type: "number" }],
nullable: true,
})
value!: CellValue;
}// main.ts
import { NestFactory } from "@nestjs/core";
import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger";
import { Module } from "@nestjs/common";
import { Cell } from "./dto";
@Module({})
class AppModule {}
async function main() {
const app = await NestFactory.create(AppModule, { logger: false });
const doc = SwaggerModule.createDocument(
app,
new DocumentBuilder().build(),
{ extraModels: [Cell] },
);
console.log(JSON.stringify(doc.components?.schemas?.Cell, null, 2));
await app.close();
}
main();{
"name": "swagger-oneof-nullable-repro",
"type": "module",
"scripts": { "start": "ts-node main.ts" },
"dependencies": {
"@nestjs/common": "^11.1.20",
"@nestjs/core": "^11.1.20",
"@nestjs/swagger": "11.4.3",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.2"
},
"devDependencies": {
"ts-node": "^10.9.1",
"typescript": "^5.9.3"
}
}pnpm installpnpm start
{
"type": "object",
"properties": {
"value": {
"type": "object",
"oneOf": [
{ "type": "string" },
{ "type": "number" }
],
"nullable": true
}
},
"required": ["value"]
}The value schema is contradictory: type: "object" requires the value to be
an object, while oneOf only permits primitives. Spectral (oas3-schema)
flags this. Generated SDK clients refuse all valid payloads.
{
"type": "object",
"properties": {
"value": {
"oneOf": [
{ "type": "string" },
{ "type": "number" }
],
"nullable": true
}
},
"required": ["value"]
}