JSON contracts
Turn JSON into TypeScript without trusting the sample
A JSON sample is evidence of one response, not a complete promise from an API. Treat generated types as a reviewable starting point.
Content updated: · Maintainer and corrections
Work through a nullable response
Paste {"id":"0042","tags":[],"profile":null} into JSON to TypeScript. The identifier is a string: keeping it as text preserves its leading zeros. The empty array supplies no evidence about an element type. The null profile supplies no evidence about properties such as name or email. Do not turn either gap into an invented contract.
Now compare a second response: {"id":"0043","tags":["beta"],"profile":{"displayName":"Example"}}. It provides evidence for string array elements and an object-shaped profile. Confirm with the API specification whether profile can be null and whether tags can be absent; a second sample still cannot prove either rule.
| Case | Interpretation and next step |
|---|---|
| Missing property | Consider optionality only after checking the API contract; absence differs from null. |
| Empty array | Collect a non-empty fixture or consult the schema before choosing an element type. |
| Numeric-looking identifier | Preserve the source string when leading zeros or exact identifiers matter. |
Start with the consumer question
Before converting a payload, decide which fields the UI or service actually reads. A field that was absent in one sample may be optional, permission-gated, or simply omitted by an upstream experiment.
Make ambiguity visible
Use a deliberately small sample that exposes the decisions you must make: string versus number identifiers, empty arrays, nullable values, and nested objects. Review the generated type before copying it into a shared contract.
Keep runtime validation separate
TypeScript disappears at runtime. A generated interface improves editor feedback, but it cannot prove untrusted JSON matches the shape. Validate at the network boundary when malformed input would change behavior or expose data.
{"id":"42","tags":[],"profile":null}Data provenance