astahmer / openapi-zod-client

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

Missing Export with recursive Schemas #199

Open spark-sse opened 1 year ago

spark-sse commented 1 year ago

Description:

I am working with a recursive schema in an OpenAPI specification file (openapi.json) and generating TypeScript types using this library. The generated types include a Zod schema for the recursive object. However, I'm facing an issue when I attempt to use the exported type in my code.

Steps to reproduce:

OpenAPI Specification (openapi.json):

{
    "openapi": "3.0.0",
    "info": {
      "title": "Recursive Example API",
      "version": "1.0.0"
    },
    "paths": {
      "/items": {
        "get": {
          "responses": {
            "200": {
              "description": "An array of items",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Item"
                  }
                }
              }
            }
          }
        }
      }
    },
    "components": {
      "schemas": {
        "Item": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            },
            "children": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/Item"
              }
            }
          }
        }
      }
    }
  }

Generated Code:

I generated the code using the following command:

$ npx openapi-zod-client openapi.json

This produces the following TypeScript code:

type Item = Partial<{
    name: string;
    children: Array<Item>;
}>;

const Item: z.ZodType<Item> = z.lazy(() =>
    z
        .object({ name: z.string(), children: z.array(Item) })
        .partial()
        .passthrough()
);

export const schemas = {
    Item
};

For reference, I export it like this in my index.ts:

export * from './api/client';

Error Encountered:

When I use the Item type, I encounter the following compiler error:

Exported variable 'router' has or is using name 'Item' from external module "[...]" but cannot be named.

Temporary Fix

I can work around this issue by manually adding an export statement to the Item type as follows:

export type Item = Partial<{
    name: string;
    children: Array<Item>;
}>;

This manual fix seems to resolve the error but there might be an underlying problem that needs addressing. I tried to use something like --export-schemas but it didn't had an effect. Any assistance or suggestions to rectify this error would be greatly appreciated!

astahmer commented 1 year ago

not sure what the solution could be, it seems more like a zod/zodios/typescript issue. I feel like exporting everything kinda pollutes the global imports across the app.

still, you can use a custom template -t, --template <path> Template path for the handlebars template that will be used to generate the output

also, if you don't need runtime validation you can use typed-openapi instead

spark-sse commented 1 year ago

We need runtime validation. Actually I don't want to use the Item type here, but for some reason it must be exported. Otherwise the compiler can't resolve the types even if I only use the Zod schema.

But thanks for the input. I will look into the template method and consider to look into zodios.

astahmer commented 1 year ago

related https://github.com/astahmer/openapi-zod-client/pull/206 thanks for the PR !