Blog
Wild & Free Tools

How to Validate JSON at Runtime in TypeScript

Last updated: April 2026 6 min read

Table of Contents

  1. Why TypeScript Types Are Not Enough at Runtime
  2. The Zod Solution: Schema That Validates at Runtime
  3. Using safeParse to Handle Errors Gracefully
  4. Validating API Responses in Practice
  5. Common Zod Methods for JSON Validation
  6. Frequently Asked Questions

TypeScript types are erased at runtime — your type annotations do not validate anything when your app is running. To validate JSON at runtime in TypeScript, you need a schema validation library like Zod that checks the actual data structure and types at execution time.

This guide shows the problem, explains why TypeScript types alone are not enough, and walks through runtime validation with Zod step by step.

Why TypeScript Types Are Not Enough at Runtime

Consider this TypeScript code:

interface User {
  id: number;
  name: string;
}

async function fetchUser(id: number): Promise<User> {
  const res = await fetch("/api/users/" + id);
  return res.json() as User; // type assertion, no actual check
}

The as User cast tells TypeScript to trust you — it does NOT check the data. If the API returns { id: "abc", name: null }, TypeScript compiles fine. Your app crashes at runtime when you try to use user.id as a number.

This gap between compile-time types and runtime data is one of the most common sources of TypeScript bugs in production.

The Zod Solution: Schema That Validates at Runtime

Zod schemas check the actual data at runtime, not just the types at compile time:

import { z } from 'zod';

const UserSchema = z.object({
  id: z.number(),
  name: z.string()
});

type User = z.infer<typeof UserSchema>;

async function fetchUser(id: number): Promise<User> {
  const res = await fetch("/api/users/" + id);
  const data = await res.json();
  return UserSchema.parse(data); // throws if invalid
}

If the API returns wrong data, parse() throws with a detailed error. Your app never silently processes corrupt data.

Sell Custom Apparel — We Handle Printing & Free Shipping

Using safeParse to Handle Errors Gracefully

Use safeParse when you want to handle errors without try/catch:

const result = UserSchema.safeParse(data);

if (!result.success) {
  // result.error contains detailed issues
  result.error.issues.forEach(issue => {
    console.error(issue.path, issue.message);
  });
  return null;
}

const user = result.data; // typed as User

safeParse returns { success: true, data: T } or { success: false, error: ZodError }. No exceptions. This pattern is clean for API handlers and service functions.

Validating API Responses in Practice

A complete example with a list endpoint:

const PostSchema = z.object({
  id: z.number(),
  title: z.string(),
  body: z.string(),
  userId: z.number()
});

const PostListSchema = z.array(PostSchema);

async function fetchPosts() {
  const res = await fetch("https://jsonplaceholder.typicode.com/posts");
  const data = await res.json();
  const result = PostListSchema.safeParse(data);

  if (!result.success) {
    throw new Error("API returned unexpected data: " + result.error.message);
  }

  return result.data; // Post[]
}

If you need to generate the schema from a real API response, paste the JSON into the free JSON to Zod converter and get a ready-made schema in seconds.

Common Zod Methods for JSON Validation

Beyond basic type matching, Zod provides format validators:

These are the constraints you add after generating a base schema. Generate the structure, then layer on the business rules.

Try It Free — No Signup Required

Runs 100% in your browser. No data is collected, stored, or sent anywhere.

Open Free JSON to Zod Converter

Frequently Asked Questions

Do TypeScript types validate data at runtime?

No. TypeScript types are erased at compile time. They exist only during development for IDE support and type checking. At runtime, JavaScript runs and types are gone — there is no built-in runtime validation.

What is the best way to validate JSON in TypeScript?

Zod is the most popular TypeScript-first option. You define a schema with z.object() and call schema.parse() or schema.safeParse() on your data. Failed validation throws an error with detailed field-level messages.

What is the difference between parse and safeParse in Zod?

parse() throws a ZodError if validation fails. safeParse() returns a result object { success, data } or { success: false, error } without throwing. Use safeParse for cleaner error handling without try/catch.

Can I generate a Zod schema from a JSON sample?

Yes. Paste your JSON into the free JSON to Zod converter at /developer-tools/json-to-zod/. It generates the full z.object() schema automatically from your data.

Launch Your Own Clothing Brand — No Inventory, No Risk