JSON Schema vs TypeScript Types: When to Use Which?
TypeScript types disappear at runtime. Learn the difference between JSON Schema and TypeScript types, how Zod fits in, and when to use each for validating JSON data.
TypeScript Types Disappear at Runtime
If you work with APIs, JavaScript, or TypeScript, you have probably used TypeScript types to describe the structure of JSON data. But there is an important limitation: TypeScript types disappear at runtime.
This raises an important question: should you use TypeScript types or JSON Schema to validate JSON data? The answer depends on what you are trying to solve.
TypeScript is excellent for catching errors while developing an application. JSON Schema is designed to describe and validate JSON data at runtime. In many production applications, using both together provides the best results.
JSON Schema vs TypeScript: The Short Answer
The biggest difference is when validation happens.
| Feature | TypeScript Types | JSON Schema |
|---|---|---|
| Main purpose | Static type checking | JSON validation |
| Validation time | Compile time | Runtime |
| Works in JavaScript runtime | No | Yes |
| Validates API responses | Not by itself | Yes |
| Describes JSON structure | Yes | Yes |
| Can be shared across languages | Limited | Yes |
| Useful for external data | Limited | Excellent |
| Works with JSON Schema validators | No | Yes |
A useful way to remember it is:
TypeScript tells your code what data should look like. JSON Schema can verify that incoming JSON actually looks that way.
What Are TypeScript Types?
TypeScript adds a static type system to JavaScript. For example:
1interface User {2 id: number;3 name: string;4 email: string;5}You can now use the User type throughout your application:
1function getUser(user: User) {2 console.log(user.name);3}TypeScript can detect incorrect code during development:
1const user: User = {2 id: "123", // Error: Type 'string' is not assignable to type 'number'3 name: "John",4 email: "john@example.com"5};The id property is supposed to be a number, so TypeScript reports an error. This is extremely useful. However, there is one important limitation.
TypeScript Does Not Validate Runtime JSON
Suppose your application receives this response from an API:
1{2 "id": "123",3 "name": "John",4 "email": "john@example.com"5}You might write:
1const user: User = await response.json();TypeScript may allow this code because you have told it that the result is a User. But TypeScript does not actually inspect the JSON response and verify that it follows the User structure. The server could return:
1{2 "id": "wrong",3 "name": 1234}What Is JSON Schema?
JSON Schema is a standard way to describe the structure, constraints, and expected data types of JSON documents. For example:
1{2 "type": "object",3 "properties": {4 "id": {5 "type": "integer"6 },7 "name": {8 "type": "string"9 },10 "email": {11 "type": "string",12 "format": "email"13 }14 },15 "required": ["id", "name", "email"]16}This schema describes a JSON object that must contain:
- An integer "id"
- A string "name"
- A valid email address
- All three properties are required
A JSON Schema validator can then check actual JSON data against these rules.
1{2 "id": 101,3 "name": "John",4 "email": "john@example.com"5}1{2 "id": "101",3 "name": "John",4 "email": "not-an-email"5}Compile-Time vs Runtime Validation
This is the most important difference between TypeScript and JSON Schema.
TypeScript: Compile-Time
TypeScript helps developers while writing and building the application. If you accidentally assign the wrong type, the compiler can warn you.
1const user: User = {2 id: 101,3 name: "John",4 email: "john@example.com"5};But after compilation, TypeScript's type information is not available for runtime validation.
JSON Schema: Runtime
JSON Schema can be used when data actually enters your application. The validator examines the actual JSON data.
1External API2 ↓3JSON response4 ↓5JSON Schema validation6 ↓7ApplicationThis makes JSON Schema particularly useful for:
- API requests
- API responses
- Configuration files
- Uploaded JSON
- External services
- Message queues
- Data exchange between applications
A Practical Example
Imagine an application that consumes a user API. The expected response is:
1{2 "id": 42,3 "name": "Alice",4 "active": true5}You might define the TypeScript type:
1interface User {2 id: number;3 name: string;4 active: boolean;5}This gives your application excellent developer tooling: autocomplete, type checking, better refactoring, and compile-time errors. But the API is external to your TypeScript compiler. It could suddenly return:
1{2 "id": "42",3 "name": "Alice",4 "active": "yes"5}Your TypeScript type doesn't automatically protect you from this response. A JSON Schema can.
Using JSON Schema for API Validation
1{2 "$schema": "https://json-schema.org/draft/2020-12/schema",3 "type": "object",4 "properties": {5 "id": {6 "type": "integer"7 },8 "name": {9 "type": "string"10 },11 "active": {12 "type": "boolean"13 }14 },15 "required": ["id", "name", "active"],16 "additionalProperties": false17}Now a validator can check the actual response. If id is a string instead of an integer, validation fails. If active is "yes" instead of true, validation fails. This is something a TypeScript interface alone cannot do at runtime.
They Solve Different Problems
It is tempting to think that one should replace the other. Usually, that isn't necessary. Think of them as two different layers.
1 Your Application2 │3 ┌──────────────┴──────────────┐4 │ │5 TypeScript JSON Schema6 │ │7 Compile-time Runtime8 │ │9 Developer code External dataTypeScript protects your application code. JSON Schema can protect your application from unexpected JSON data.
What About Zod?
If you work with TypeScript, you may also have encountered Zod, a TypeScript-first validation library.
1import { z } from "zod";23const UserSchema = z.object({4 id: z.number(),5 name: z.string(),6 email: z.string().email()7});You can then validate runtime data:
1const result = UserSchema.safeParse(data);This makes Zod very useful in TypeScript applications. The ecosystem can look like this:
1JSON2 ↓3Zod validation4 ↓5TypeScript applicationJSON Schema and Zod are not identical technologies, though. JSON Schema is a standardized JSON-based schema language with broad interoperability. Zod is a TypeScript validation library designed primarily for application development.
JSON Schema vs TypeScript vs Zod
| Technology | Primary Purpose | Runtime Validation | Cross-Language |
|---|---|---|---|
| TypeScript | Static typing | No | No |
| JSON Schema | JSON structure and validation | Yes | Yes |
| Zod | TypeScript validation | Yes | Primarily TypeScript |
So which one should you use? That depends on your application.
When Should You Use Which?
Data inside your application:
- Function parameters
- Component props
- Internal objects
- Application state
- Return types
- Database models
- Reusable interfaces
1interface Product {2 id: number;3 title: string;4 price: number;5}Data that crosses a system boundary:
- Public APIs
- API request validation
- API response validation
- Configuration files
- JSON imports
- Webhooks
- Event payloads
- Data exchange
- Documentation
- Contract validation
A good rule is:
If the JSON comes from somewhere you don't completely control, runtime validation is worth considering.
When Should You Use Both?
For many production TypeScript applications, using both is a strong approach. This gives you protection at two different levels.
1External API2 ↓3JSON Schema validation4 ↓5Validated JSON6 ↓7TypeScript application8 ↓9TypeScript type checkingJSON Schema
Protects against unexpected external data.
TypeScript
Protects developers from incorrect usage of that data inside the application.
JSON Schema and OpenAPI
JSON Schema also has an important relationship with API development. OpenAPI is widely used to describe HTTP APIs, and modern OpenAPI versions use a JSON Schema-based vocabulary for describing data structures. For example, an API specification can describe a request body:
1type: object2required:3 - name4 - email5properties:6 name:7 type: string8 email:9 type: string10 format: emailThat schema can then be used by different tools for things such as:
- API documentation
- Request validation
- Code generation
- Testing
- Client generation
This is one reason JSON Schema is more than just a validation format. It can become part of an application's data contract.
Can JSON Schema Generate TypeScript Types?
Yes. Because JSON Schema formally describes data structures, tools can generate TypeScript types from schemas.
1JSON Schema2 ↓3TypeScript types1TypeScript2 ↓3JSON SchemaThe reverse direction is also possible with suitable tooling. However, the conversion is not always perfectly one-to-one. TypeScript and JSON Schema have different type systems and capabilities, so generated schemas or types may require adjustments.
Which One Should You Choose?
Use this simple decision guide.
Choose TypeScript when
- You control the data.
- You need compile-time safety.
- You are defining internal application structures.
- You want IDE autocomplete and developer tooling.
Choose JSON Schema when
- Data comes from external systems.
- You need runtime JSON validation.
- Multiple programming languages consume the same data.
- You are defining an API contract.
- You want a standardized JSON schema format.
Use both when
- You are building a production TypeScript application.
- Your application consumes external JSON.
- API contracts are important.
- You want both runtime validation and compile-time safety.
Common Mistake: Assuming Types Validate API Responses
One of the most common mistakes in TypeScript applications is this:
1const user = await response.json() as User;The as User syntax does not validate anything. It simply tells TypeScript:
Treat this value as a User.
It does not inspect the JSON. For untrusted data, you need actual runtime validation. That validation can come from JSON Schema, Zod, or another runtime validation solution.
The Best Mental Model
Instead of thinking “JSON Schema vs TypeScript”, think:
JSON Schema for data boundaries, TypeScript for application code.
1 External World2 │3 ▼4 JSON payload5 │6 ▼7 Runtime validation8 JSON Schema / Zod9 │10 ▼11 Trusted application data12 │13 ▼14 TypeScript15 │16 ▼17 Application codeThis separation makes the roles much clearer.
Final Verdict
There is no universal winner between JSON Schema and TypeScript. They solve related but different problems. TypeScript types are primarily for developers and compile-time safety. JSON Schema is primarily for describing and validating JSON data at runtime.
If you are building a small internal TypeScript application, TypeScript types may be enough. If you are consuming external APIs or exchanging JSON between systems, JSON Schema can provide an important validation layer. And for larger production applications, combining JSON Schema and TypeScript can provide the best of both worlds: standardized data contracts, runtime validation, and strong developer tooling.
Frequently Asked Questions
Internal data → TypeScript. External JSON → JSON Schema.
Once you understand the difference between compile-time types and runtime validation, choosing between JSON Schema and TypeScript becomes much easier.