8000 v4: toJSONSchema `.default()` `.catch()` input values considered non optional · Issue #4134 · colinhacks/zod · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

v4: toJSONSchema .default() .catch() input values considered non optional #4134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
samchungy opened this issue Apr 13, 2025 · 1 comment
Closed

Comments

@samchungy
Copy link
Contributor
samchungy commented Apr 13, 2025

Something tricky to deal with in my library when generating JSON Schema from Zod Types was figuring out whether to generate an input (request) type or a output (response) type. I assume that was the intention of the pipes parameter.

The current required implementation only considers the output type.

return shape[k]._zod.qout === "true";

I considered changing optional

optional: string[];

to a function instead of a getter which takes an optional output defaulted pipes value but that lead me down a rabbit hole... Keen to help you implement this but I understand that this might require quite a bit of tinkering.

console.log(
  JSON.stringify(
    z.toJSONSchema(
      z.object({
        jobId: z.string().default("foo"), // or .catch()
      }),
      {
        reused: "ref",
        pipes: "input",
      }
    ),
    null,
    2
  )
);
{
  "type": "object",
  "properties": {
    "jobId": {
      "type": "string",
      "default": "foo"
    }
  },
  "required": [
    "jobId"
  ]
}

In this scenario jobId should not be marked as required.

@samchungy samchungy changed the title v4: toJSONSchema .default() .catch() considered non optional v4: toJSONSchema .default() .catch() input values considered non optional Apr 13, 2025
@colinhacks
Copy link
Owner

The pipes param has been generalized to io. As you pointed out, input & output types diverge for a number of different schema types (not just pipes). ZodDefault is now reflected as optional with io: "input".

import * as z from "zod";

console.log(
  JSON.stringify(
    z.toJSONSchema(
      z.object({
        jobId: z.string().default("foo"), // or .catch()
      }),
      {
        reused: "ref",
        io: "input",
      }
    ),
    null,
    2
  )
);

/**
 * {
  "type": "object",
  "properties": {
    "jobId": {
      "type": "string",
      "default": "foo"
    }
  },
  "required": []
}
 */

I think .catch() is a little trickier. Arguably the equivalent JSON Schema for ZodCatch is {} (anything) but in practice I don't think it makes sense to throw away all the type information here. The .catch() functionality is Zod-specific and it's safe to assume that in most cases you'll want the input to conform to the schema instead of just defaulting to the catch fallback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants
0