astahmer / openapi-zod-client

Generate a zodios (typescript http client with zod validation) from an OpenAPI spec (json/yaml)
openapi-zod-client.vercel.app
809 stars 87 forks source link

TypeScript error: Type is too long to infer, needs explicit type annotation. #308

Open wembleyoz opened 2 months ago

wembleyoz commented 2 months ago

Read before opening

Describe the bug When generating the client from a large OpenAPI schema, such as the one at LCU OpenAPI schema, the following TypeScript error is encountered: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed.

The error seems to occur due to the size and complexity of the generated schema and type inference limits in TypeScript.

Minimal reproduction

Expected behavior I expect the generated code to either handle larger schemas gracefully or suggest adding explicit type annotations to avoid the TypeScript inference error. The code should look like the example provided, which avoids importing large objects directly and instead exports each schema individually.

Additional context

Suggested improvement Instead of importing large schemas as a whole (schemas = {...all_schemas}), export individual schemas to avoid the same issue with TypeScript’s type inference limits.

Schematic example of the suggested code change:

import { makeApi, Zodios, type ZodiosOptions, ZodiosInstance } from "@zodios/core";
import { z } from "zod";

{{#if imports}}
{{#each imports}}
import { {{{@key}}} } from "./{{{this}}}"
{{/each}}
{{/if}}

{{#if types}}
{{#each types}}
{{{this}}};
{{/each}}
{{/if}}

{{#ifNotEmptyObj schemas}}
{{#each schemas}}
export const {{@key}}{{#if (lookup ../emittedType @key)}}: z.ZodType<{{@key}}>{{/if}} = {{{this}}};
{{/each}}
{{/ifNotEmptyObj}}

const endpoints = makeApi([
{{#each endpoints}}
    {
        method: "{{method}}",
        path: "{{path}}",
        {{#if @root.options.withAlias}}
        {{#if alias}}
        alias: "{{alias}}",
        {{/if}}
        {{/if}}
        {{#if description}}
        description: `{{description}}`,
        {{/if}}
        {{#if requestFormat}}
        requestFormat: "{{requestFormat}}",
        {{/if}}
        {{#if parameters}}
        parameters: [
            {
                name: "{{name}}",
                {{#if description}}
                description: `{{description}}`,
                {{/if}}
                type: "{{type}}",
                schema: {{{schema}}}
            },
            {{/each}}
        ],
        response: {{{response}}},
        errors: [
            {
                status: {{status}},
                description: `{{description}}`,
                schema: {{{schema}}}
            }
        ]
    },
{{/each}}
]);

export const apiClient: ZodiosInstance<typeof endpoints> = new Zodios(endpoints);

export function createApiClient(baseUrl: string, options?: ZodiosOptions) {
    return new Zodios(baseUrl, endpoints, options);
}
ChrisSargent commented 1 week ago

We are also running in to this issue. Tried the above but we also get the errors in the createApiClient function and the const endpoints = makeApi.

Our only workaround I think right now is to group the endpoints. Any other guidance would be appreciated.

wembleyoz commented 4 days ago

We are also running in to this issue. Tried the above but we also get the errors in the createApiClient function and the const endpoints = makeApi.

Our only workaround I think right now is to group the endpoints. Any other guidance would be appreciated.

You can just replace the variable apiClient with

export const apiClient: ZodiosInstance<typeof endpoints> = new Zodios(endpoints);

ChrisSargent commented 4 days ago

We are also running in to this issue. Tried the above but we also get the errors in the createApiClient function and the const endpoints = makeApi. Our only workaround I think right now is to group the endpoints. Any other guidance would be appreciated.

You can just replace the variable apiClient with

export const apiClient: ZodiosInstance<typeof endpoints> = new Zodios(endpoints);

not for us, it just shifts the same error to the const endpoints line....