TypeScript to JSON Schema
Paste TypeScript interface or type declarations and get a JSON Schema (draft 2020-12) in return. The first declaration becomes the root schema; the rest are collected under and linked with . Primitives map to their schema types, T[] and Array<T> become array schemas, string-literal unions become enums, and optional ? properties are dropped from required. Everything runs in your browser.
How to use the TypeScript to JSON Schema
Paste one or more TypeScript declarations into the input. Both interface Name { ... } and type Name = { ... } forms are supported, and you can paste several at once. Click Generate. The first declaration in the paste is treated as the root schema and emitted at the top level, with $schema set to the draft 2020-12 dialect; any other declarations become entries under $defs, and a property whose type is one of those names is emitted as a {"$ref": "#/$defs/Name"} pointer.
Within each declaration, every property line is parsed for its name, an optional ? marker, and its type. Type mapping is pragmatic: string, number, boolean, and null map to the matching JSON Schema types; T[] and Array<T> become {"type": "array", "items": ...}; a union of string literals such as 'a' | 'b' becomes {"enum": ["a", "b"]}; and an inline { ... } object becomes a nested object schema. Properties without a ? are listed in the schema's required array; optional ones are omitted. Use Copy for the result or Example to load two interfaces where one references the other so you can see the $ref/$defs wiring.
TypeScript types and JSON Schema draft 2020-12
TypeScript types and JSON Schema solve overlapping problems from opposite ends. TypeScript describes shapes for the compiler and erases them at runtime; JSON Schema describes shapes as data so they can validate a payload at runtime, document an API in OpenAPI, or constrain the output of a tool or LLM. Translating from a TypeScript type to a schema lets a single source of truth in your code drive runtime validation, form generation, or API documentation without re-describing the shape by hand.
This converter targets draft 2020-12, the current JSON Schema dialect, which is why the output carries "\$schema": "https://json-schema.org/draft/2020-12/schema" and uses \$defs for reusable subschemas rather than the older definitions keyword. References between schemas use a JSON Pointer, {"\$ref": "#/\$defs/Address"}, exactly as a hand-written 2020-12 schema would. Keeping the dialect explicit matters because validators behave differently across drafts — tuple handling, items versus prefixItems, and \$ref resolution all changed over time.
The parser here is deliberately pragmatic rather than a full TypeScript compiler. It recognises the common surface that real DTOs use: object interfaces and type aliases, optional properties, primitive types, arrays in both T[] and Array<T> notation, string-literal unions (mapped to enum), inline object literals, and references to other declared names. Advanced constructs — generics, mapped and conditional types, intersections, template-literal types — are beyond a regex-level parser and should be flattened before pasting. For the reverse direction, generating TypeScript from data, the JSON to TypeScript tool infers interfaces from a JSON sample.
Common use cases
- Runtime validation — turn a compile-time TypeScript type into a schema you can enforce with Ajv or any JSON Schema validator.
- OpenAPI / Swagger — produce the component schemas an API spec needs from the types you already maintain.
- LLM structured output — convert a TypeScript response type into the JSON Schema a model's structured-output or function-calling API expects.
- Config validation — generate a schema for a config type so a CI step can validate config files before deploy.
- Form generation — feed the schema to a JSON-Schema-driven form library to render an editor for the type.
- Contract sharing — hand a language-agnostic schema to non-TypeScript services that consume the same data.
Frequently asked questions
Which JSON Schema draft does it emit?
"\$schema": "https://json-schema.org/draft/2020-12/schema" and uses \$defs (not the legacy definitions) for reusable subschemas, with \$ref JSON Pointers between them.How are optional properties handled?
? is omitted from the schema's required array but still appears under properties. Properties without ? are listed as required.What happens with references between interfaces?
\$defs. A property typed as one of those names is emitted as {"\$ref": "#/\$defs/Name"} so the schema stays DRY and self-contained.How are unions and arrays mapped?
'a' | 'b' becomes {"enum": ["a","b"]}. Both T[] and Array<T> become {"type":"array","items":...} with the element type mapped recursively.