What to check: email is a union of string and null; phone is optional. Turn optional inference off to make phone required, which rejects Sample 1 as a complete ApiUser.
Absent keys and null values mean different things; neither proves the full contract.
What to check: id and profile.age are a union of number and string. items uses an item interface with qty: a union of number and null. nickname and discount are optional; disabling inference makes them required.
The observed values form unions; strings are not turned into date or enum types.
export type ApiPayload = ApiPayloadItemItem[];
export interface ApiPayloadItemItem {
id: number | string;
"display-name": string | null;
active?: boolean;
}
Initial options: Root name api-payload; optional fields on; unknown[] fallback.
What to check: The name becomes ApiPayload. A root type alias and its object-item interface are both emitted; display-name is quoted. Change the root name to 9-response to get _9Response.
Generated names can collide in other inputs. Check declarations against the real payloads.
What the sample-based inference can tell you
Paste one or two JSON payloads. Object fields missing from some samples become optional when the option is enabled; observed values contribute string, number, boolean, null, array or nested-object types. The output is a draft for review, with copy and .ts download.
Object roots generate interfaces; array and primitive roots generate type aliases. Arrays of objects also include their item interfaces. Load the cases below to inspect exact outputs and reset the root name, optional-field option and empty-array fallback together.
Usage Boundaries & Limitations
Optional means a key was absent from the observed object samples. Null is a value type, and all-null samples infer null. Neither observation proves the complete API contract, enum range or future behavior.
Disabling optional inference makes missing fields required, so the generated draft may reject one of the input samples. Empty arrays use unknown[] by default or any[] if selected; populated samples supply the observed element types.
Do not combine an object root and a non-object root in one run. The page stops rather than letting the engine silently omit non-object samples. Compare those response shapes separately.
Generated interface names come from field names, so different names that normalize to the same identifier can collide. Review nested declarations and run your own compiler and contract tests; successful compilation alone does not prove a faithful API model.
Input uses strict JSON.parse. Large integers can lose precision, and inference runs on the main thread with input-dependent memory costs. No fixed file-size or processing-speed guarantee is made.
Frequently Asked Questions (FAQ)
What is the difference between an optional field and a nullable field?▼
A missing key in some object samples can produce ?. A present key with string and null values produces a union of string and null. A field present as null in every sample produces null, without discovering unseen non-null values.
How do nested objects and arrays contribute types?▼
Observed nested objects are merged into named interfaces, and array elements are combined into an element type. Object-array roots use a type alias plus item declarations. This is sample-based inference, without schema validation or semantic record matching.
Why do empty arrays use unknown[] or any[]?▼
When every observed array is empty, there is no element evidence. The selected fallback is used. If another sample contains strings, that field becomes string[]. Choosing any[] weakens checking; the fallback does not prove the real API element type.
Can I use the generated TypeScript as the final API contract?▼
Review it first. Missing fields, null values and unions reflect the supplied samples. Disabled optional inference can reject those samples, normalized names can collide, and dates or enums remain strings. Use API documentation, more responses and strict compiler tests.