Skip to content

[Bug]: alova gen 通过 openapi 生成 Apis,对于复杂 requestBody 生成类型错误 #802

@seepine

Description

@seepine

这是否是一个 Bug?

  • 我已经确认我要报告的是一个 Bug

这个问题是否已经存在?

  • 我已经确认这个 Issue 没有被报告过

Alova 版本

3.5.0

前端框架

Vue

问题描述

对于后端oauth token接口,对于 grant_type 值不同,参数也不同,json如下

  "paths": {
    "/oauth/token": {
      "post": {
        "tags": [
          "auth"
        ],
        "security": [
          {
            "HTTP Bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "grant_type": {
                        "type": "string",
                        "const": "password"
                      },
                      "username": {
                        "type": "string",
                        "minLength": 1
                      },
                      "password": {
                        "type": "string",
                        "minLength": 1
                      },
                      "scope": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "grant_type",
                      "username",
                      "password"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "grant_type": {
                        "type": "string",
                        "const": "authorization_code"
                      },
                      "code": {
                        "type": "string",
                        "minLength": 1
                      },
                      "redirect_uri": {
                        "type": "string",
                        "format": "uri"
                      },
                      "client_id": {
                        "type": "string"
                      },
                      "client_secret": {
                        "type": "string"
                      },
                      "scope": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "grant_type",
                      "code",
                      "redirect_uri",
                      "client_id",
                      "client_secret"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "grant_type": {
                        "type": "string",
                        "const": "refresh_token"
                      }
                    },
                    "required": [
                      "grant_type"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "grant_type": {
                        "type": "string",
                        "enum": [
                          "client_credentials",
                          "device_code"
                        ]
                      },
                      "scope": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "grant_type"
                    ],
                    "additionalProperties": false
                  }
                ]
              }
            },
          }
        }
      }

而生成的类型为

Image

期望的表现

多类型复合,例如

data: {
    grant_type: "password";
    username: string;
    password: string;
    scope?: string;
} | {
    grant_type: "authorization_code";
    code: string;
    redirect_uri: string;
    client_id: string;
    client_secret: string;
    scope?: string;
} | {
    grant_type: "refresh_token";
} | {
    grant_type: "client_credentials" | "device_code";
    scope?: string;
}

复现链接

No response

复现步骤

通过elysia+zod简单创建接口(或任意后端

import { Elysia } from 'elysia'
import { openapi } from '@elysiajs/openapi'

const schema = z.union([
  z.object({
    grant_type: z.literal('password'),
    username: z.string().min(1, 'username is required'),
    password: z.string().min(1, 'password is required'),
    scope: z.string().optional(),
  }),
  z.object({
    grant_type: z.literal('authorization_code'),
    code: z.string().min(1, 'code is required'),
    redirect_uri: z.url('redirect_uri must be a valid URL'),
    client_id: z.string(), // 可选,也可以通过 Basic Auth 提供
    client_secret: z.string(), // 可选,也可以通过 Basic Auth 提供
    scope: z.string().optional(), // 可选的权限范围
  }),
  z.object({
    grant_type: z.literal('refresh_token'),
  }),
  z.object({
    grant_type: z.enum(['client_credentials', 'device_code']),
    scope: z.string().optional(),
  })
])

const app = new Elysia()
  .post(
    '/token',
    async ({ body }) => {},
   {
     body: schema
   }
  .use(openapi())
  .listen(3000)

系统信息

System:
    OS: macOS 15.3.1
    CPU: (10) arm64 Apple M4
    Memory: 132.42 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 24.2.0 - /Users/seepine/.nvm/versions/node/v24.2.0/bin/node
    npm: 11.3.0 - /Users/seepine/.nvm/versions/node/v24.2.0/bin/npm
    pnpm: 10.10.0 - /Users/seepine/.nvm/versions/node/v24.2.0/bin/pnpm
    bun: 1.3.8 - /Users/seepine/.bun/bin/bun
    Watchman: 2025.05.19.00 - /opt/homebrew/bin/watchman
  Browsers:
    Chrome: 143.0.7499.170
    Safari: 18.3
  npmPackages:
    alova: ^3.5.0 => 3.5.0 
    vue: ^3.5.13 => 3.5.13

补充说明

swagger-ui 可正常识别

Image

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions