glideapps / quicktype

Generate types and converters from JSON, Schema, and GraphQL
https://app.quicktype.io
Apache License 2.0
12.31k stars 1.07k forks source link

converting a recursive json schema into a zod type breaks #2508

Open jonnytest1 opened 7 months ago

jonnytest1 commented 7 months ago

example self referential schema:

{
  "id": "http://json-schema.org/geo",
  "$schema": "http://json-schema.org/draft-06/schema#",
  "description": "A geographical coordinate",
  "type": "object",
  "definitions":{
    "Mydef1":{
        "type":"object",
        "properties":{
            "test":{
                "$ref":"#/definitions/Mydef1"
            }

        }
    }
  },
  "properties": {
    "latitude": {
       "$ref":"#/definitions/Mydef1"
    }
  }
}

produces:

export const Mydef1Schema = z.object({
    "test": z.union([Mydef1Schema, z.null()]).optional(),
});
export type Mydef1 = z.infer<typeof Mydef1Schema>;

export const CoordinateSchema = z.object({
    "latitude": z.union([Mydef1Schema, z.null()]).optional(),
});
export type Coordinate = z.infer<typeof CoordinateSchema>;

but it should be https://github.com/colinhacks/zod#recursive-types

=> z.lazy(() => Mydef1Schema)

export const Mydef1Schema = z.object({
    "test": z.union([z.lazy(() =>Mydef1Schema), z.null()]).optional(),
});
export type Mydef1 = z.infer<typeof Mydef1Schema>;

export const CoordinateSchema = z.object({
    "latitude": z.union([Mydef1Schema, z.null()]).optional(),
});
export type Coordinate = z.infer<typeof CoordinateSchema>;
jonnytest1 commented 7 months ago

a relatively easy approach would probably be to wrap ALL schemas into z.lazy 🤔 which should work fine at least for the runtime evaluation