SwaggerV3不支持AnyOf数据类型
- Dominant language
- TypeScript
- Stars
- 3k
- Forks
- 251
- PR merge metrics
- No merged PRs in 30d
Description
## What happens(发生了什么)?
SwaggerV3 JSON文档生成时,`api.d.ts`中的AnyOf类型字段会被直接生成any。具体对比如下:

另外还有以下两种特殊情况:
1、生成类型错误:
对于ValidationError的定义如下:
```json
"ValidationError": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
}
```
生成的错误类型如下:
```ts
export class ValidationError {
/** loc ---------------array类型错误 ----------- */
loc: array
/** msg */
msg: string
/** type */
type: string
}
```
2、这种特殊结构也需要单独处理:
```json
"vehicle_series_ids": {
"anyOf": [
{
"items": {
"type": "integer"
},
"type": "array"
},
{
"type": "null"
}
],
"title": "Vehicle Series Ids",
"description": "车系id列表, None时为全部"
},
```
## How To Reproduce(如何重现)
完整的Swagger文档如下:
```json
{
"openapi": "3.1.0",
"info": {
"title": "FastAPI API Docs",
"description": "FastAPI todo swagger",
"version": "1.0.0"
},
"paths": {
"/todo/": {
"get": {
"tags": [
"todo"
],
"summary": "Get Todo List",
"operationId": "get_todo_list_todo__get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TodoListResponse"
}
}
}
}
}
}
},
"/todo/{id}": {
"post": {
"tags": [
"todo"
],
"summary": "Get Todo List",
"operationId": "get_todo_list_todo__id__post",
"parameters": [
{
"description": "Todo的id",
"required": true,
"schema": {
"type": "integer",
"title": "Todo的id",
"description": "Todo的id"
},
"name": "id",
"in": "path"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TodoItem"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
}
},
"/": {
"get": {
"summary": "Index",
"operationId": "index__get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {}
}
}
}
}
}
}
},
"components": {
"schemas": {
"HTTPValidationError": {
"properties": {
"detail": {
"items": {
"$ref": "#/components/schemas/ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
},
"Role": {
"properties": {
"id": {
"type": "integer",
"title": "Id"
},
"role_name": {
"type": "string",
"title": "Role Name"
}
},
"type": "object",
"required": [
"id",
"role_name"
],
"title": "Role"
},
"TodoItem": {
"properties": {
"id": {
"type": "integer",
"title": "Id"
},
"title": {
"type": "string",
"title": "Title"
},
"completed": {
"type": "boolean",
"title": "Completed"
},
"complete_at": {
"type": "string",
"format": "date-time",
"title": "Complete At"
},
"creator": {
"$ref": "#/components/schemas/User"
},
"field1": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
],
"title": "Field1"
},
"field2": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
],
"title": "Field2"
},
"field3": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
],
"title": "Field3"
},
"field4": {
"items": {
"type": "string"
},
"type": "array",
"title": "Field4"
},
"field5": {
"type": "boolean",
"title": "Field5"
},
"field6": {
"type": "boolean",
"title": "Field6",
"default": true
},
"field7": {
"type": "boolean",
"title": "Field7",
"description": "是否为营运, None时为全部"
}
},
"type": "object",
"required": [
"id",
"title",
"completed",
"complete_at",
"field1"
],
"title": "TodoItem"
},
"TodoListResponse": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/TodoItem"
},
"type": "array",
"title": "Data"
},
"page": {
"type": "integer",
"title": "Page"
},
"page_size": {
"type": "integer",
"title": "Page Size"
},
"total": {
"type": "integer",
"title": "Total"
}
},
"type": "object",
"required": [
"data",
"page",
"page_size",
"total"
],
"title": "TodoListResponse"
},
"User": {
"properties": {
"id": {
"type": "integer",
"title": "Id"
},
"username": {
"type": "string",
"title": "Username"
},
"role": {
"$ref": "#/components/schemas/Role"
}
},
"type": "object",
"required": [
"id",
"username"
],
"title": "User"
},
"ValidationError": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
}
}
}
}
```
Contributor guide
Research direction
Start by tracing the SwaggerV3-to-TypeScript generation path that produces api.d.ts, using the supplied OpenAPI document as the reproduction input. Cover top-level anyOf, array items containing anyOf, and anyOf combining an array with null; done means generated declarations preserve these alternatives without invalid any typing or array types.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- openapi, typescript
- Domain
- api, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100