JSON to Types

Optional vs nullable fields

A missing key is optional; a null value is nullable. They are different types, and conflating them is a common source of runtime surprises.

Input

[
  { "id": 1, "middleName": "Byron", "deletedAt": null },
  { "id": 2, "deletedAt": "2026-01-05T00:00:00Z" }
]

An array of one object shape.

1 interface · 3 fields · 2 levels deep

Where this sample is ambiguous

  • Check this

    Optionality inferred from one sample

    `[].middleName` was missing from at least one object in the sample and is therefore marked optional. A single sample cannot distinguish "sometimes omitted" from "omitted in this particular payload".

    Fix: Check these against the real schema. Absent means optional; a null value would instead mean present-and-nullable, which is a different type.

  • Note

    Whole numbers are still `number`

    Every numeric value in the sample was a whole number, but JSON has a single number type and cannot express the difference. The output uses `number`.

    Fix: If a field is genuinely an integer, tighten it by hand: `z.number().int()`.

TypeScript

export interface RootItem {
  id: number;
  middleName?: string;
  deletedAt: null | string;
}

export type Root = RootItem[];

Zod

import { z } from 'zod';

export const RootItemSchema = z.object({
  id: z.number(),
  middleName: z.string().optional(),
  deletedAt: z.string().nullable(),
});

export const RootSchema = z.array(RootItemSchema);

Convert your own JSON

Paste a sample on the home page, or call the API or MCP server. This page is also available as markdown.

Related examples