JSON to TypeScript Converter
Generate TypeScript declarations from JSON or JSON Lines samples, with optional-field evidence, null policies, guard code, and review notes.{{ result.typesCode }}
{{ result.guardCode }}
| Path | Type | Status | Evidence | Copy |
|---|---|---|---|---|
| {{ row.path }} | {{ row.type }} | {{ row.status }} | {{ row.evidence }} |
| Level | Area | Evidence | Action | Copy |
|---|---|---|---|---|
| {{ row.level }} | {{ row.area }} | {{ row.evidence }} | {{ row.action }} |
TypeScript types are often needed before a formal API schema exists. A developer may have an API response, a webhook event, a fixture, a settings file, or a set of log records, but no written contract. Turning those samples into declarations helps editors, compilers, tests, and reviewers agree on the shape that code expects.
JSON has a small value vocabulary: objects, arrays, strings, numbers, booleans, and null. TypeScript describes code expectations with a larger vocabulary that includes interfaces, type aliases, optional properties, unions, arrays, tuples, readonly properties, and fallback types. The difficult part is not translating "name" to string; it is deciding what the sample proves and what it merely suggests.
| JSON Evidence | TypeScript Question | Review Caution |
|---|---|---|
| A key is missing from some sampled objects | Should the property use ?? | A small sample can make a required production field look optional. |
| A value appears as both text and a number | Should the type become a union? | Mixed kinds may show inconsistent upstream data rather than an intended contract. |
| An array always has the same short length | Is it a tuple or an ordinary list? | Use tuples only when each position has stable meaning. |
A field is only null in the sample | Should it stay nullable, become optional, or fall back? | Null can mean explicit empty value, unavailable data, or incomplete evidence. |
Sample quality controls how much confidence a generated declaration deserves. A single happy-path response can hide optional error fields, pagination cursors, nullable metadata, empty arrays, alternate status values, and large numeric identifiers that cannot be represented exactly as JavaScript numbers. JSON Lines can be useful for event streams because each nonblank line contributes another sample object.
A declaration is compile-time help, not runtime proof. It can improve code completion and catch mismatched property access, but it does not stop a server, queue, file, or user from sending a different shape later. Values at untrusted boundaries still need validation, tests, or guard code when the program cannot safely assume the sample is complete.
How to Use This Tool:
Start with the most representative JSON sample available, then choose the policies that should shape optional fields, nulls, arrays, and declaration style.
- Set Root type name to a PascalCase name for the payload, event, configuration object, or fixture. The summary shows the normalized root name after a successful parse.
- Choose Declaration style and Emit mode. Interfaces suit object-heavy data, type aliases suit union or tuple roots, exported declarations fit normal application code, and namespace mode groups the generated declarations under one wrapper.
- Pick Missing properties before using an array of object samples. Optional when absent in array samples is usually safest for records gathered from several responses because keys missing from some objects become optional.
- Choose Null handling. Nullable unions keep explicit
null, optional-from-null treats null-only fields as optional, and fallback choices useunknownoranywhen no non-null sample exists. - Paste Sample JSON, browse a
.json,.jsonl, or.txtfile, or drop text onto the input area. One complete JSON value is parsed first; multi-line input is treated as JSON Lines only when every nonblank line is valid JSON.Selected files must be readable JSON or text files smaller than 2 MB. Extra dropped files are ignored after the first file. - Open Advanced when you need Readonly fields, stable sorted keys, small repeated string literal unions, fixed-position tuple inference, or a different Fallback type for empty arrays and unsupported evidence.
- Review Generated Types, Runtime Guard, Inference Ledger, Review Notes, and Type Profile. Fix parse errors first, then check optional markers, date-like strings, empty arrays, unsafe integers, and quoted property names before copying the TypeScript.
Interpreting Results:
Read the generated declarations as a typed draft of the current sample. Generated Types is the code handoff, but Inference Ledger and Review Notes explain why the draft looks that way and where it may be too narrow, too broad, or based on thin evidence.
Runtime Guard is a starter check for the inferred root value and top-level required fields. It can catch the wrong root kind or a missing required property, but it is not a full schema validator for nested business rules, allowed status values, numeric ranges, or date parsing.
- Use the summary counts to check field count, declaration count, nesting depth, optional-field count, and whether the input parsed as JSON or JSON Lines.
- Use Inference Ledger to verify present counts before accepting optional properties in arrays of objects.
- Use Review Notes to catch date-like strings, email-like or URL-like strings, empty arrays, unsafe integers, null-only paths, literal unions, and quoted property names.
- Use Type Profile to spot complexity such as many unions, optional fields, arrays, object declarations, or deep nesting.
- Compare output from several real samples before treating the declarations as a shared API, event, or configuration contract.
Technical Details:
JSON object members are string names paired with JSON values, and arrays are ordered sequences of values. TypeScript object types describe the properties code expects to read, whether each property may be absent, and what value kinds can appear. Inference has to turn observed runtime values into static declarations without pretending the sample is a complete specification.
Optionality is based on evidence and policy. When an array contains several object samples, a key present in every object can be treated differently from a key seen in only some objects. Null needs separate handling because null is an explicit JSON value, while an optional TypeScript property represents a property that may be missing or undefined in code.
Array shape also depends on meaning. Ordinary API lists usually merge item samples into one item type. Fixed-position arrays are clearer as tuples only when each position has stable meaning, such as a coordinate pair or a compact protocol record.
Transformation Core:
| Stage | Rule Used | What to Verify |
|---|---|---|
| Parse sample | Try one complete JSON value first. If that fails and multiple valid nonblank JSON lines exist, treat those lines as an array of samples. | Fix the reported JSON position or JSON Lines row before trusting generated code. |
| Name shapes | Normalize the root name to PascalCase and derive nested names from parent paths and property names. | Rename the root when generated names are too generic for the project. |
| Infer primitives | Map strings, numbers, booleans, arrays, objects, and nulls to TypeScript primitives, declarations, unions, or fallback types. | Mixed value kinds may reveal inconsistent upstream data. |
| Infer object properties | Collect observed keys, infer each property value, then apply missing-key, null, readonly, and property-order choices. | Optional markers should match the real contract, not just the current sample. |
| Infer arrays | Merge item samples by default. Tuple mode is used only for fixed lengths from 1 to 8 when every sampled array has the same length. | Choose tuples only when positions carry stable meaning. |
| Emit declarations | Output interfaces or type aliases, then wrap them as exported declarations, ambient declarations, or a namespace according to the selected mode. | The same inferred shape can be valid in several TypeScript styles. |
Policy Effects:
| Choice | Output Effect | Risk if Misread |
|---|---|---|
| Missing properties | Controls whether absent keys become optional, every observed key is required, or all properties are optional. | A partial sample can loosen or tighten the contract incorrectly. |
| Null handling | Emits | null, optional properties, unknown, or any for null-only evidence. | Null may mean explicit empty value, hidden data, or missing upstream data. |
| String inference | Keeps strings wide, reports recognizable formats, or emits small repeated literal unions. | Narrow literal unions can break when production sends a new open-text value. |
| Array inference | Creates merged item arrays or fixed-length tuples. | Tuple output is misleading for ordinary lists whose length can grow or shrink. |
| Fallback type | Uses unknown, any, or never where no concrete item or non-null value exists. | any can hide mistakes, while never may be too strict for incomplete samples. |
String inference is intentionally conservative. Date-like values, email addresses, URLs, and UUID-like values remain string unless the consuming code validates or converts them later. Literal unions are reserved for small repeated string sets, with open-text identifiers left wide.
JSON numbers need a precision check when they carry identifiers. JavaScript can represent integer values exactly only through Number.MAX_SAFE_INTEGER, which is 9,007,199,254,740,991. Larger integer IDs may need to be strings so comparisons, copies, and round trips stay exact.
Worked Transformation Path:
For three sampled order records where discount_code is "WELCOME10" in one record, null in another, and absent in the third, nullable handling can add | null while optional-when-missing adds ?. The resulting property describes observed evidence; the production contract still needs to confirm whether the field is truly optional, nullable, both, or required with a non-null value.
Privacy Notes:
Pasted text, dropped text, and selected files are parsed in the browser for this conversion. The generated declarations, runtime guard, ledger rows, review notes, type profile chart data, and JSON result summary are created from the current page state. Avoid pasting secrets, tokens, private customer data, or production credentials into samples that you plan to copy, download, or share.
Worked Examples:
Order event sample
An order event with id, type, created_at, customer.email, and an items array should produce a root declaration plus nested customer and item shapes. Review Notes may flag created_at as date-like text because JSON has no native date value.
JSON Lines event stream
Three nonblank JSON Lines records for user.created, user.updated, and user.deleted are treated as an array sample when every line parses. Under optional-when-missing, Inference Ledger marks fields seen in all three records as required and fields seen in only one or two records as optional.
Coordinate tuple
A coordinate value such as [40.7128, -74.0060] is a better tuple candidate than a shopping-cart item list. With tuple inference, Generated Types can preserve two fixed number positions; with merged array inference, the same value becomes a list of numbers.
Unsafe numeric identifier
A payload containing "account_id": 9007199254740993 should trigger a Review Notes warning about unsafe integers. For an ID that must be copied, compared, or stored exactly, change the upstream contract or sample so the identifier is represented as a string.
FAQ:
Should I choose interfaces or type aliases?
Choose interfaces when the generated declarations are mostly object shapes that may be extended. Choose type aliases when the root can be an array, tuple, primitive, or union, or when your project prefers aliases for generated types.
Why did a property become optional?
With Optional when absent in array samples, a property becomes optional when it is missing from at least one sampled object in an array. Check Inference Ledger to see how many sample objects contained that path.
Why are dates generated as strings?
JSON stores date and date-time values as strings. The date-note string policy can flag recognizable values in Review Notes, but the generated type stays string unless you change it later or add runtime conversion in your own code.
Can I paste JSON Lines instead of one JSON array?
Yes. When the input has multiple nonblank lines and every line is valid JSON, the converter treats those lines as array samples and reports JSONL in the summary.
Why is an empty array typed as unknown, any, or never?
An empty array has no item evidence. The Fallback type setting decides what appears until you provide a sample with at least one item or manually choose the intended item type.
Does the runtime guard replace a schema validator?
No. The guard checks the inferred root shape and top-level required properties. Use a schema validator or hand-written checks when nested rules, allowed ranges, strict status values, or business constraints matter.
Does my JSON sample leave the browser?
The conversion reads pasted text and selected files in the browser. Be careful with sensitive samples if you copy generated declarations, export tables, download the JSON result, or share the output.
Glossary:
- Declaration
- A TypeScript interface or type alias that names an inferred JSON shape.
- Optional property
- A property written with
?because the selected policy treats missing or null evidence as optional. - Union type
- A TypeScript type that allows more than one value kind, such as
string | numberorItem | null. - Tuple
- A fixed-position array type where each index can have its own meaning and type.
- JSON Lines
- A text format where each nonblank line is a separate valid JSON value.
- Runtime guard
- A TypeScript check that verifies the inferred root shape well enough for a first pass.
- Inference Ledger
- The result table that records each JSON path, inferred type, required or optional status, and sample evidence.
References:
- RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format, RFC Editor, December 2017.
- JSON Lines, JSON Lines documentation.
- Everyday Types, TypeScript documentation.
- Object Types, TypeScript documentation.
- Number.MAX_SAFE_INTEGER, MDN Web Docs, Oct 22, 2025.