type alias JsonValue
Since 0.4.0

A value JSON.stringify can serialize.

Recursive: an array's elements and an object's property values are themselves JsonValues, so a nested payload is checked all the way down rather than only at its top level.

The object arm admits undefined deliberately. JSON.stringify drops a property whose value is undefined rather than failing, so { note: string | undefined } — the shape an optional field takes once it is written out — is serializable and is accepted here. What the type rejects is the set JSON.stringify cannot represent: bigint (which throws), plus functions and symbols (which it silently drops, losing data the caller believed it was sending).

Three limits are worth knowing before you reach them, and none is expressible in a type. A circular structure throws at runtime; no type can express acyclicity. A named interface is not assignable, because TypeScript grants implicit index signatures only to object-literal types — declare the payload with a type alias, or extend Record<string, JsonValue | undefined>. And NaN, Infinity and -Infinity are members of number that JSON has no representation for: JSON.stringify normalizes each of them to null rather than failing, so the value is silently changed rather than refused. TypeScript cannot exclude them from number, and a runtime check would mean walking every payload on the hot path — send the number as a string when the distinction matters.

Examples

Example 1

const payload: JsonValue = { build: 412, tags: ['live'], note: undefined };

Definition

string
| number
| boolean
| null
| readonly JsonValue[]
| { readonly [key: string]: JsonValue | undefined; }

Usage

import { type JsonValue } from "common/src/index.ts";