"category": "code-generator",
JSON Schema to TypeScript Converter
"tldr": Paste a JSON Schema and get TypeScript interfaces - required vs optional respected, enums become unions, nullable types handled.
Paste a JSON Schema and get TypeScript interfaces that honor the schema semantics: properties missing from the required array become optional (?), enum keywords become literal union types, ["string","null"] type arrays become string | null, and nested objects become named interfaces.
This is strictly better than generating types from a sample document when a schema exists - the schema knows which fields are optional and what the allowed enum values are, information no single sample can carry.
How to convert JSON Schema to TypeScript
- 1Paste your JSON Schema into the input panel.
- 2Properties not listed in required become optional with ?.
- 3enum keywords become literal unions; type arrays with null become | null.
- 4Copy the interfaces into your codebase.
Convert JSON Schema to TypeScript in code
import Ajv from "ajv";
import type { Root } from "./generated";
const ajv = new Ajv();
const validate = ajv.compile(schema);
if (validate(data)) {
const typed = data as Root; // safe: just validated against the same schema
}# for $ref-heavy schemas, the npm package handles full composition
npx json-schema-to-typescript schema.json > types.d.tsFrequently asked questions
Which schema keywords are supported?
The structural core: type (including arrays with null), properties, required, items, and enum - which covers the overwhelming majority of hand-written schemas. $ref/$defs, allOf/oneOf composition, and constraint keywords (patterns, ranges) are not expanded; for schemas heavy on those, use the json-schema-to-typescript npm package.
Interfaces only exist at compile time - what enforces the schema at runtime?
Nothing, by design - TypeScript types are erased. Pair the interfaces with runtime validation: validate with ajv against the same schema, or generate a Zod schema instead (our Schema to Zod tool) which gives you both the runtime check and the inferred type from one source.
Why did integer become number?
TypeScript has no integer type - number is the only numeric primitive. The integer constraint remains enforceable only at runtime (ajv checks it; Zod expresses it as z.number().int()).
How should I keep schema and types in sync?
Make the schema the source of truth and regenerate types in CI or a codegen script whenever it changes. Hand-editing generated interfaces is how the two drift apart - the exact problem schemas exist to prevent.
Last updated:
You might also need
Free and in-browser, like everything on JSON Console. Browse all tools →