General-purpose JSON types for TypeScript. Use them for API data, configuration, and other JSON data in frontend and Node.js projects when you don’t need to define the exact shape of an object. Unlike Record<string, any>, these types limit values to JSON-compatible types, including nested objects and arrays.
npm i @okutils/json-dThis is a types-only package, so use import type:
import type { JSONObject } from "@okutils/json-d";
const user: JSONObject = {
id: 1,
name: "Xiaoming",
active: true,
avatar: null,
tags: ["TypeScript", "React"],
profile: {
city: "Shanghai",
settings: { darkMode: true },
},
};import type { JSONObject } from "@okutils/json-d";
const getDisplayName = (user: JSONObject): string => {
const name = user.name;
return typeof name === "string" ? name.toUpperCase() : "Anonymous user";
};
getDisplayName({ name: "Alice" }); // "ALICE"
getDisplayName({ id: 1 }); // "Anonymous user"This example fetches a JSON object from /api/user.
import { useEffect, useState } from "react";
import type { JSONObject } from "@okutils/json-d";
export const Foo = () => {
const [data, setData] = useState<JSONObject | null>(null);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const controller = new AbortController();
const fetchData = async () => {
try {
const response = await fetch("/api/user", {
signal: controller.signal,
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
const value: unknown = await response.json();
// A JSON response can also be an array, a scalar, or null.
if (
value === null ||
typeof value !== "object" ||
Array.isArray(value)
) {
throw new Error("Expected a JSON object from the API");
}
if (!controller.signal.aborted) {
setData(value as JSONObject);
}
} catch (error) {
if (!controller.signal.aborted) {
setError(error instanceof Error ? error.message : "Request failed");
}
}
};
void fetchData();
return () => controller.abort();
}, []);
if (error !== null) return <p role="alert">{error}</p>;
if (data === null) return <p>Loading…</p>;
const name = typeof data.name === "string" ? data.name : "Anonymous user";
return (
<section>
<h2>{name}</h2>
<pre>{JSON.stringify(data, null, 2)}</pre>
</section>
);
};Use JSONScalar for values that can be strings, numbers, booleans, or null:
import type { JSONScalar } from "@okutils/json-d";
const formatCell = (value: JSONScalar): string => {
if (value === null) return "—";
if (typeof value === "boolean") return value ? "Yes" : "No";
return String(value);
};
formatCell("Xiaoming"); // "Xiaoming"
formatCell(42); // "42"
formatCell(false); // "No"
formatCell(null); // "—"
// formatCell({ name: 'Xiaoming' }); // Type error: objects are not allowed
// formatCell(['TypeScript']); // Type error: arrays are not allowedUse JSONValue when your data can be any JSON value: a scalar, an object, or an array. For example, this browser utility saves JSON data to localStorage:
import type { JSONValue } from "@okutils/json-d";
const saveJSON = (key: string, value: JSONValue): void => {
localStorage.setItem(key, JSON.stringify(value));
};
saveJSON("theme", "dark");
saveJSON("pageSize", 20);
saveJSON("notifications", true);
saveJSON("selection", null);
saveJSON("user", { id: 1, name: "Xiaoming" });
saveJSON("recentUsers", [
{ id: 1, name: "Xiaoming" },
{ id: 2, name: "Xiaohong" },
]);
// Readonly arrays are supported too, including those created with `as const`.
saveJSON("coordinates", [121.47, 31.23] as const);