Skip to main content
Ink·tab

Infer interfaces from samples

Paste an API response and get a TypeScript interface back, ready to drop in.

TypeScript
export interface Address {
  city: string;
  zip: string;
}

export interface PostsItem {
  title: string;
  views: number;
}

export interface Root {
  address: Address;
  age: number;
  email: null;
  id: string;
  name: string;
  posts: PostsItem[];
  tags: string[];
}

Everything happens in your browser. Nothing is uploaded.

When to use it

When all you have of an API is a sample response — no schema, no TypeScript SDK. Hand-typing the interface tends to miss fields.

Inference rules

  • Objects — fields are inferred recursively, and identical shapes are reused under the same interface name.
  • Arrays — element types are merged into a union. An empty array becomes unknown[].
  • null — default is T | null. Toggling Treat null as optional rewrites those fields as field?: T instead.
  • Primitives — string, number, boolean.

Options

  • Root interface name — defaults to Root. Pick whatever fits the model you're describing.
  • Add export — emits export interface ….
  • Treat null as optional — clearer in strict-null-check codebases.

Limits

  • Polymorphic responses (the same field varying type across calls) can't be inferred from one sample. Merge a few payloads by hand if you need a union.
  • Non-JSON values (functions, symbols, BigInt) aren't part of the source format and are ignored.

API schema inference — response stays local

JSON.parse + recursive type-builder, both in-house. Identical-shape objects are deduplicated automatically. Sample API responses never leak outside.

Frequently asked questions

Are deeply nested JSON structures handled?
Yes. Recursive inference handles arbitrarily nested objects and arrays. Objects sharing the same shape across multiple locations reuse a single interface to avoid duplicate definitions.
How are null values inferred?
Default is `T | null` union. With 'Optional' on, the field becomes `T?` (optional property). Pick based on whether your API distinguishes nullable from missing.
Does it emit interface or type alias?
Uses the `interface` keyword — friendly for `extends` and declaration merging. Replace with `type` directly if you need a type alias.