MiServe DevTools

Your lid

Pin tools here. They are saved in this browser.

JSON to Go Struct & TypeScript Converter

Turn a JSON sample into Go structs, TypeScript interfaces or types, or a JSON Schema, with optional keys, null and dates detected.

Runs in your browser. Nothing you paste is uploaded.

About this tool

What is inferred from the sample

The tool walks the JSON value and records what it finds at every position. The elements of an array are merged into one description: a key that some of the objects lack becomes optional, a value that is sometimes null becomes nullable, and an array holding values of different kinds becomes a union in TypeScript and []any in Go.

A number is an integer only if every sample of it is written without a decimal point or an exponent and fits in a signed 64-bit integer; otherwise it is a floating-point number. A string becomes a date-time only if every sample is an RFC 3339 date-time such as 2026-11-14T10:00:00Z. A date without a time stays a string.

Each nested object gets a type named after its key. For the elements of an array the name is made singular when the key is a plain English plural, so users gives User and categories gives Category; otherwise Item is appended. With Inline nested types the nested objects are written inside their parent instead.

The Go output

Field names are exported and follow the Go convention for initialisms, so user_id becomes UserID and html_url becomes HTMLURL, while the json tag keeps the original key. Integers are int, or int64 when a sample does not fit in 32 bits, because the Go specification lets int be 32 bits wide. Other numbers are float64 and date-times are time.Time. The distinction between 1 and 1.0 matters: encoding/json refuses to decode 1.0 into an int field.

With Add omitempty to optional fields switched on, a key that is missing from some samples gets omitempty in its tag and keeps its plain type. A scalar or a struct that can be null becomes a pointer, such as *string, so that null and the zero value stay distinct; a slice or a map needs no pointer, because it can be nil. A value that is only ever null becomes any. Optional nested structs and optional time.Time fields become pointers as well, because omitempty never omits a struct value. The columns are aligned the way gofmt aligns them.

Some keys cannot be bound to a struct field. No json tag can name an empty key or a key that contains a comma, a quote or a backslash. The original encoding/json also ignores a tag name that contains anything other than letters, digits and common punctuation, so a key with a combining mark or an emoji is matched only by the implementation based on encoding/json/v2. When the sample has such keys, the tool lists them under the output.

The TypeScript and JSON Schema output

In TypeScript an optional key is written with ?:, a nullable value with | null, and a key that is not a valid identifier is quoted. Date-times are typed as string, since that is what JSON.parse returns, with a comment that marks them. The interface and the type alias forms describe the same shape; choose the one your code base uses.

The JSON Schema output follows draft 2020-12. Keys present in every sample are listed under required, integers are integer, date-times carry format: date-time, and named object types are placed under $defs and referenced with $ref.

A sample shows what one document looked like, not everything an API can send. Check the optional and nullable fields against the documentation of the API before you rely on the result.

Questions

How does the tool know that a field is optional?

It can tell only from arrays. When the objects of one array do not all have the same keys, a key that is missing from at least one of them is optional. A single object gives no evidence, so all of its keys are treated as required.

Why is one number an int and another a float64?

A number is typed as an integer when every sample of it is written without a decimal point or exponent and fits in a 64-bit integer. In Go that is int, or int64 when a sample is outside the 32-bit range. If a single sample is 2.5, or is written as 1.0, the field becomes float64 in Go and number in JSON Schema. TypeScript uses number for all of them.

What happens when a value is null?

If the same field also has a non-null sample, the type becomes nullable: in Go a pointer, or a slice or map, which can already be nil; in TypeScript a union with null; in JSON Schema a schema that also accepts null. If null is the only sample, nothing is known about the real type, so the result is any in Go and null in TypeScript and JSON Schema.

Is my JSON sent to a server?

No. The types are generated by JavaScript in your browser tab. The tool makes no network request with what you paste, and the site's security policy blocks requests to any other host.

More in Data