JSON to TypeScript: Interface vs Zod Schema — What to Generate
Table of Contents
When converting JSON to TypeScript, you have two options: generate a plain TypeScript interface (type-only, no runtime checking) or generate a Zod schema (types plus runtime validation). For data that only lives inside your codebase, an interface is fine. For data that crosses a system boundary — API responses, user input, environment config — a Zod schema is the safer choice.
This page compares both outputs, shows what each generates from the same JSON, and explains when each is the right call.
What Each Approach Generates
Starting JSON:
{
"id": 1,
"name": "Alice",
"email": "[email protected]",
"roles": ["admin", "editor"],
"createdAt": "2024-01-15T10:00:00Z"
}
TypeScript interface output:
interface User {
id: number;
name: string;
email: string;
roles: string[];
createdAt: string;
}
Zod schema output (from the free converter):
const UserSchema = z.object({
id: z.number(),
name: z.string(),
email: z.string(),
roles: z.array(z.string()),
createdAt: z.string()
});
type User = z.infer<typeof UserSchema>;
The interface is compile-time only. The Zod schema gives you compile-time types AND runtime validation in one definition.
The Problem with Plain Interfaces at Runtime
TypeScript interfaces are erased when compiled to JavaScript. At runtime, there is no trace of them. This means:
// This compiles without errors
const user: User = await fetch("/api/user/1").then(r => r.json()) as User;
// But if the API returns:
// { "id": "not-a-number", "name": null, "roles": "admin" }
// TypeScript has no idea. Your code crashes at runtime.
The as User cast is a lie to TypeScript. It trusts you that the data matches. It does not check.
Zod catches the mismatch at parse time:
const result = UserSchema.safeParse(data);
if (!result.success) {
// result.error tells you exactly which fields are wrong
}
Sell Custom Apparel — We Handle Printing & Free Shipping
When a Plain Interface Is Fine
Plain interfaces work well for data that never comes from outside your codebase:
- Function return types that are constructed internally
- Component props in a fully type-checked React tree
- Internal state shapes where all values are set by your own code
- Config objects that are hardcoded in your codebase
In these cases, TypeScript's compile-time checks are enough because the data never comes from an untrusted source.
Use Zod when the data crosses a system boundary: API calls, form submissions, file reads, URL params, environment variables, or anything from a third party.
Generating a Zod Schema Instead of an Interface
To generate a Zod schema (which gives you both the type and runtime validation) from your JSON:
- Paste your JSON into the free JSON to Zod converter
- Copy the generated
z.object()schema - Add
import { z } from 'zod';at the top - Add
export type YourType = z.infer<typeof YourSchema>;to extract the TypeScript type
You now have one definition that serves as both the TypeScript interface AND the runtime validator. No duplication, no drift between type and implementation.
Try It Free — No Signup Required
Runs 100% in your browser. No data is collected, stored, or sent anywhere.
Open Free JSON to Zod ConverterFrequently Asked Questions
Should I generate a TypeScript interface or a Zod schema from JSON?
For data from APIs, forms, or external sources, generate a Zod schema — it provides runtime validation plus TypeScript types in one definition. For purely internal data shapes, a plain interface is fine.
Can I get a TypeScript type from a Zod schema?
Yes. Use z.infer
How is a Zod schema different from a TypeScript interface?
A TypeScript interface exists only at compile time and is erased from the JavaScript output. A Zod schema exists at runtime and can actually check whether data matches the expected shape when your code runs.
Is there a free tool to generate Zod schemas from JSON?
Yes. Paste your JSON into the free converter at /developer-tools/json-to-zod/. It generates the full z.object() schema with correct types for every field. No signup, runs in your browser.

