Search DevTools

Jump to any tool or page

Type → Zod Schema Generator

Paste a TypeScript type or interface and get Zod schema instantly.

Input

paste a TypeScript type or interface

Output

Generate the schema and it appears here.

Developer Utilities

About Zod Schema Generator

Paste a JSON sample or a TypeScript interface and get a Zod schema that validates it at runtime. The gap this closes is that TypeScript types are erased at compile time and enforce nothing against data crossing a network boundary; a Zod schema is a value that runs, and z.infer derives the static type from it so the two cannot drift apart.

Frequently asked questions

How does the generator infer types from a single JSON sample?
It reads the runtime shape, which means the output is a hypothesis, not a specification. A null in the sample cannot be distinguished from an optional field, an empty array gives no element type, and a field that happens to be an integer in this payload is typed as z.number() with no clue whether it is ever fractional. Treat the generated schema as a first draft: widen unions, add .optional() or .nullable() where the API contract allows it, and tighten the numeric constraints yourself.
What is the difference between optional, nullable and default?
They address three different absences. .optional() makes the key permitted to be missing and adds undefined to the type. .nullable() permits an explicit null while still requiring the key. .default(v) accepts missing input and substitutes a value, so the output type has no undefined even though the input type does — which is why Zod distinguishes z.input from z.output on such schemas. JSON has no undefined, so APIs almost always mean nullable where a TypeScript developer would write optional.
Why does my object drop properties the sample clearly had?
z.object strips unknown keys by default: parse returns a new object containing only the declared shape. That is a safety feature, not a bug, but it surprises people who log the parsed result and find fields gone. Use .passthrough() to retain unknown keys, or .strict() to reject them with an error instead of silently discarding them. On a discriminated union, strictness matters more, since an unexpected key may be the only signal that you are validating the wrong variant.
How should I validate dates and numeric strings from JSON?
JSON has no date type, so a timestamp arrives as a string or a number. z.date() will reject the string outright. Use z.iso.datetime() to validate an ISO 8601 string and keep it a string, or z.coerce.date() to parse it into a Date — noting that coercion is permissive and will happily accept anything the Date constructor tolerates. Similar care applies to numeric strings: z.coerce.number() turns "" into 0 and "12abc" into NaN unless you also constrain it.
What is the performance cost of validating on every request?
Zod compiles nothing ahead of time; parse walks the schema tree per call, so cost scales with payload size and nesting depth. For typical API payloads this is microseconds and irrelevant beside the network. It becomes measurable on large arrays — validating ten thousand rows per request is real work — and on regex-heavy string checks, where a poorly written pattern can backtrack catastrophically. Define schemas once at module scope rather than rebuilding them inside a handler, and use safeParse to avoid exceptions on the hot path.