TS_TO_ZOD_V1

TypeScript to Zod

Paste a TypeScript interface or type alias and get a matching z.object, z.union, or z.enum. Optional fields become .optional(), unions with null become .nullable().

TypeScript input310 B
Zod output3 schemas · 627 B
import { z } from "zod";

export const AddressSchema = z.object({
  city: z.string(),
  zip: z.string(),
});
export type Address = z.infer<typeof AddressSchema>;

export const RoleSchema = z.enum(["admin", "author", "reader"]);
export type Role = z.infer<typeof RoleSchema>;

export const UserSchema = z.object({
  id: z.number(),
  name: z.string(),
  email: z.string().optional(),
  role: RoleSchema,
  address: AddressSchema,
  tags: z.array(z.string()),
  metadata: z.record(z.string(), z.unknown()),
  createdAt: z.date(),
  manager: z.lazy(() => UserSchema).nullable(),
});
export type User = z.infer<typeof UserSchema>;
check_circleParsed
Lines
24
Schemas
3

What gets mapped?

  • Primitives: string, number, boolean, bigint, Date, etc.
  • Literal types: "foo" / 42 become z.literal(...). A union of string literals becomes z.enum(...).
  • Generic refs: Array<T>, Record<K, V>, Partial<T>, Promise<T>, Map<K, V>, Set<T>.
  • Index signatures ([key: string]: T) become .catchall(zT).
  • Cross-references between your declarations use the generated XSchema; self/forward references are wrapped in z.lazy.

What does it skip?

Generic type parameters on your own declarations (interface Page<T> { data: T }), conditional types, mapped types, and template literal types aren't represented. They'll either fall back to z.unknown()with an inline note, or trigger a parse error you can fix in place.

Is my code sent anywhere?

No. Parsing and code generation run synchronously in your browser. Nothing is uploaded, logged, or stored.