JSON to TypeScript: sample inference, optional fields and validation
Use generated TypeScript as a starting point, then review nulls, empty arrays, missing fields and large IDs. Understand why formatting can change signed bytes.
A sample is an observation, not the whole contract
A response containing a name and email does not prove that every record has an email or that it can never be null. Generating TypeScript from JSON saves typing, but describes the sample in front of you.
Review optional fields, union types and business constraints against the API contract. Where available, examine representative responses with empty collections and missing fields as well as the normal case.
Formatting helps people read
Indentation makes nested structures easier to inspect; it does not validate their business meaning. Valid JSON can still contain the wrong currency unit, timestamp format or identifier.
Consistent formatting can reduce visual noise when comparing responses. A text diff shows character changes, and you still need to decide whether those changes represent different API behavior.
A type declaration does not validate a response at runtime
TypeScript declarations help check application code during development. They do not automatically turn received network data into a trusted object. Runtime validation belongs in the application where required.
Use sample-derived types as a draft, revise them against the real contract, and retain appropriate error handling. Generated output is not a complete API specification.
Signature checks need the original bytes
HMAC operates on message bytes. JSON documents can parse to equivalent objects yet produce different digests after whitespace, line endings or key order changes. Do not substitute a formatted copy for the original signed message.
Use redacted responses and test keys in Neatbo, and confirm that input encoding matches the protocol. Browser-local calculation reduces data transfer but does not replace key management or access controls.
Compare a normal response with an incomplete one
The two example records differ in more than their values: email is absent in the second and tags is empty. One example cannot tell you whether the absent property is legal or a server defect. Resolve that question from the API contract before deciding whether a TypeScript property should be optional.
An empty array gives no evidence about its allowed element type. Likewise, a single non-null value does not prove null is impossible. Build a small set of representative examples, including error responses, and keep the contract decisions separate from generated syntax.
For identifiers, distinguish the numeric representation from the business meaning. A long decimal-looking ID often belongs as a string. Converting a rounded JavaScript number to a string later does not recover lost digits; preserve the intended representation at the input boundary.
| Observation | Question to resolve | Where to resolve it |
|---|---|---|
| Property missing | Optional or defective? | API contract and server behavior |
| Empty array | Which element types are legal? | Schema or representative responses |
| null value | Nullable in all states? | Business rules |
| Long identifier | Text or arithmetic quantity? | Producer and consumer agreement |
[
{"id":"00123","email":"[email protected]","tags":["new"]},
{"id":"00456","tags":[]}
]Before you finish
- Review the generated type before placing it in production code.
- Test missing, null and empty-collection states.
- Validate untrusted responses at the application boundary when required.
- Keep raw signed payloads unchanged for signature calculations.
References
- TypeScript Handbook: Everyday Types
Reference for optional properties, unions and type assertions; inferred samples still require contract review.