PK Systems PK Systems
Developer tools

JSON to TypeScript / Go / Rust

Paste any JSON sample. Get clean TypeScript interfaces, Go structs, or Rust types with serde tags — fast, lightweight, and ready to paste into your code.

JSON to TypeScript / Go / Rust

Output

Output appears here as you type.

What this converter does

It walks a JSON sample, infers a type for every value, and emits an idiomatic type definition in your chosen language. Objects become interfaces (TypeScript), structs (Go, Rust), and nested objects produce sibling type definitions. Arrays of objects unify their element shapes — fields present in some items but not others are marked optional, and primitive values that vary (string in some items, integer in others) collapse to a union or to serde_json::Value in Rust. No data is sent anywhere — the entire inferrer runs in your browser.

How to use it

Paste a representative JSON payload (one record from your API response, ideally), pick the target language, and copy the result. If your JSON has multiple instances of the same shape (a paginated list, for example), include the array — the inferrer learns more from variance. The casing toggle renames fields in the output without touching the JSON keys themselves; for Go and Rust the original key is preserved as a struct tag so serialisation round-trips.

Tips and gotchas

  • Optional vs nullable: a field missing from some records becomes ? / Option<T>, but a field present everywhere with a literal null value becomes a union with null — the two are different and inferred separately.
  • Numbers: integers stay integers in Go and Rust (int64, i64); floats become float64 / f64. TypeScript collapses both to number because the language doesn't distinguish.
  • Empty arrays: [] infers to unknown[] / []interface{} / Vec<serde_json::Value> — drop a sample item in to get a real type.
  • Field renaming: only the inferrer renames fields. Your JSON parser still needs to map keys — Go uses the json: struct tag, Rust uses #[serde(rename = ...)].

Frequently asked questions

How does it handle arrays of mixed types?
It unifies element shapes. If an array contains [1, 2, "x"], the element type becomes number | string. If it contains [{a: 1}, {a: 1, b: 2}], the element becomes one object type with a required and b optional. In Go and Rust where unions don't have a clean equivalent, mixed primitives collapse to interface{} / serde_json::Value.
Does it handle deeply nested structures?
Yes — there's no depth limit. Each nested object is named after its parent key (capitalised, singularised when the parent is plural), and an internal table prevents name collisions by appending a numeric suffix. Self-referential structures like trees aren't auto-detected; you may need to merge two generated types by hand if your data forms a cycle.
Why are my Go field names PascalCase even when I picked preserve?
Go requires exported struct fields to start with a capital letter — that's a language rule, not a style choice. Lowercase field names would be private and invisible to encoding/json. The original JSON key is preserved in the json: tag, so serialisation still produces the input casing.
How is this different from heavyweight code generators?
Enterprise generators support dozens of target languages, JSON Schema input, discriminated unions, named enums and multi-pass refinement — useful when you have a formal schema and a large team. This tool is a lightweight, no-fuss inferrer with TypeScript, Go, and Rust output and no setup. For one-shot "give me a type for this API response" workflows, it is faster and the output is easier to skim and edit by hand.
Will my output compile?
Almost always yes for TypeScript. Go and Rust output is also compilable as-is, but you may need to add the right imports (use serde::{Deserialize, Serialize}; for Rust is included; Go's encoding/json is implicit). If your JSON keys collide with reserved words after renaming, Rust uses r# raw identifiers automatically.
Is anything sent to a server?
No. The parser is the browser's JSON.parse and the inferrer is a small recursive function on this page. Open DevTools > Network and you'll see no requests fire while you type. Safe for production payloads, internal API responses, and anything you wouldn't paste into a hosted SaaS.