Typing a third-party API with no published types
Capture a real response, generate the interface, then correct optionality and unions against the documentation. Far faster than writing it by hand.
Generates TypeScript interfaces or types from a JSON sample.
Generates TypeScript interfaces or types from a JSON sample.
{"id":1,"name":"Ada","tags":["admin","dev"]}interface Root { id: number; name: string; tags: string[]; }Property types are inferred from the sample values.
Each JSON value maps to the narrowest TypeScript type that fits the sample.
Your input is sent to YAS infrastructure because the tool requires server-side processing or public network queries. Input is not stored.
curl -X POST "https://yas.sh/api/v1/tools/json-to-ts" \
-H "Content-Type: application/json" \
-d '{"input":"{\"name\":\"Jane\",\"age\":30}","name":"User"}'const res = await fetch("https://yas.sh/api/v1/tools/json-to-ts", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"input": "{\"name\":\"Jane\",\"age\":30}",
"name": "User"
}),
});
const data = await res.json();import requests
r = requests.post("https://yas.sh/api/v1/tools/json-to-ts", json={"input":"{\"name\":\"Jane\",\"age\":30}","name":"User"})
data = r.json()| Field | Type | Required | Description |
|---|---|---|---|
| input | string | Yes | JSON object |
| name | string | No (default Root) | Interface name |
{ "result": "interface User {\n name: string;\n age: number;\n}", "interfaceName": "User" }Generate TypeScript interfaces from a JSON object.
400 VALIDATION_ERROR — invalid input or unsupported option.413 PAYLOAD_TOO_LARGE — input exceeds the 64 KB limit.429 RATE_LIMIT_EXCEEDED — rate limit exceeded (60 req/min).The sample JSON is parsed and each value inspected to infer a type: strings become string, numbers become number, booleans boolean, null becomes null, objects become nested interfaces, and arrays become the union of their element types. Nested objects are hoisted into named interfaces so the output is readable rather than a single deeply inlined structure.
Inference from one sample is inherently incomplete, and knowing why matters more than the output itself. A field absent from the sample cannot be marked optional; a field that is null in the sample but a string elsewhere infers as null; and an empty array gives no element type at all. The generated interface describes the example, not the contract — treat it as a starting point you then reconcile against the API documentation.
Capture a real response, generate the interface, then correct optionality and unions against the documentation. Far faster than writing it by hand.
Test fixtures and seed data are already representative samples; generating types from them keeps tests and implementation aligned.
Existing API responses give the shapes you need to declare, which is usually the largest single chunk of a migration.
A generated interface is a concrete, reviewable artefact that colleagues can correct, unlike a verbal description.
What this tool deliberately does not do, and where it will disagree with other implementations.