这是indexloc提供的服务,不要输入任何密码
Skip to content

[Zod Plugin] Variable used before declaration in OpenAPI schema with recursive and self-referential types #2560

@mvanschellebeeck

Description

@mvanschellebeeck

Description

Description

I have a complex OpenAPI schema with a lot of self-referential and recursive types that shows a typing issue Block-scoped variable 'myVariable' used before its declaration when the zod schemas are generated.

Offending OpenAPI Spec

The is the simplest OpenAPI spec I could reproduce this issue with is:

Click to open spec
{
  "openapi": "3.0.1",
  "paths": {},
  "components": {
    "schemas": {
      "ArrayType": {
        "type": "object",
        "properties": {
          "itemSchema": {
            "$ref": "#/components/schemas/Schema"
          }
        }
      },
      "TableColumn": {
        "type": "object",
        "properties": {
          "arrayElement": {
            "$ref": "#/components/schemas/TableColumn"
          },
          "columnRef": {
            "$ref": "#/components/schemas/Column"
          }
        }
      },
      "Column": {
        "type": "object",
        "properties": {
          "schema": {
            "$ref": "#/components/schemas/Schema"
          }
        }
      },
      "DataType": {
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "array": "#/components/schemas/ArrayType",
            "struct": "#/components/schemas/StructType"
          }
        },
        "oneOf": [
          {
            "$ref": "#/components/schemas/StructType"
          },
          {
            "$ref": "#/components/schemas/ArrayType"
          }
        ]
      },
      "Schema": {
        "type": "object",
        "properties": {
          "dataType": {
            "$ref": "#/components/schemas/DataType"
          },
          "nullable": {
            "type": "boolean"
          }
        }
      },
      "StructType": {
        "type": "object",
        "properties": {
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Column"
            }
          }
        }
      }
    }
  }
}

Running npx @hey-api/openapi-ts on the above spec returns zod schemas with this typing issue:

Image

Expected Output

I'd expect a z.lazy call to wrap the zArrayType as so:

export const zDataType = z.union([
    z.object({
        type: z.literal('struct')
    }).and(zStructType),
    z.object({
        type: z.literal('array')
-  }).and(zArrayType)
+  }).and(z.lazy(() => zArrayType))
]);

Reproducible example or configuration

Run npx @hey-api/openapi-ts in terminal and view type error in generated/zod.gen.ts

https://stackblitz.com/edit/stackblitz-starters-r6cydqoq?file=generated%2Fzod.gen.ts

OpenAPI specification (optional)

{
  "openapi": "3.0.1",
  "paths": {},
  "components": {
    "schemas": {
      "ArrayType": {
        "type": "object",
        "properties": {
          "itemSchema": {
            "$ref": "#/components/schemas/Schema"
          }
        }
      },
      "TableColumn": {
        "type": "object",
        "properties": {
          "arrayElement": {
            "$ref": "#/components/schemas/TableColumn"
          },
          "columnRef": {
            "$ref": "#/components/schemas/Column"
          }
        }
      },
      "Column": {
        "type": "object",
        "properties": {
          "schema": {
            "$ref": "#/components/schemas/Schema"
          }
        }
      },
      "DataType": {
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "array": "#/components/schemas/ArrayType",
            "struct": "#/components/schemas/StructType"
          }
        },
        "oneOf": [
          {
            "$ref": "#/components/schemas/StructType"
          },
          {
            "$ref": "#/components/schemas/ArrayType"
          }
        ]
      },
      "Schema": {
        "type": "object",
        "properties": {
          "dataType": {
            "$ref": "#/components/schemas/DataType"
          },
          "nullable": {
            "type": "boolean"
          }
        }
      },
      "StructType": {
        "type": "object",
        "properties": {
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Column"
            }
          }
        }
      }
    }
  }
}

System information (optional)

  "dependencies": {
    "@hey-api/openapi-ts": "^0.82.0",
    "zod": "^4.1.5"
  }

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug 🔥Something isn't workingjavascriptPull requests that update Javascript code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions