| title | Guide Documents > JSON > stringify() functions |
|---|
import { Tabs } from "nextra/components";
import LocalSource from "../../../components/LocalSource";
JSON.stringify(value) is general-purpose: it walks the value at runtime, asking each property "are you a number? a string? an array?". typia replaces that runtime walk with a hand-written stringifier generated from the TypeScript type at compile time. The result is up to ~10× faster than JSON.stringify — and, because the stringifier only knows how to serialize T, you can also opt into validating T before serialization.
namespace json {
function stringify<T>(input: T): string; // dedicated stringifier
function isStringify<T>(input: T | unknown): string | null; // is + stringify
function assertStringify<T>(input: T | unknown): string; // assert + stringify
function validateStringify<T>(input: T | unknown): IValidation<string>; // validate + stringify
}import typia from "typia";
interface User {
id: string;
age: number;
hobbies: string[];
}
const text: string = typia.json.stringify<User>({
id: "1",
age: 25,
hobbies: ["reading"],
});
// → '{"id":"1","age":25,"hobbies":["reading"]}'The output is identical to JSON.stringify({ id, age, hobbies }). The speed comes from the compiled code: instead of "for each property, dispatch to the right encoder," the emitted JS just concatenates strings in the order your type declares.
| Function | Validates input? | On failure |
|---|---|---|
json.stringify<T> |
No | undefined behavior (don't pass wrong-typed values) |
json.isStringify<T> |
Yes (is) |
returns null |
json.assertStringify<T> |
Yes (assert) |
throws TypeGuardError |
json.validateStringify<T> |
Yes (validate) |
returns IValidation<string> |
Caution
json.stringify<T> skips validation by design.
The generated code assumes its input already matches T. If you hand it a wrong-typed value, the output will be garbage (missing fields, fields with the wrong contents). Use it only when the type of the input is statically guaranteed — for example, you just built the object inside the same function. Otherwise, pick isStringify / assertStringify / validateStringify.
<Tabs items={["TypeScript Source", "Compiled JavaScript"]}> <Tabs.Tab> </Tabs.Tab> <Tabs.Tab> </Tabs.Tab>
<Tabs items={[typia, IValidation.ts, TypeGuardError.ts]}>
<Tabs.Tab>
export namespace json {
export function stringify<T>(input: T): string;
export function isStringify<T>(input: T | unknown): string | null;
export function assertStringify<T>(input: T | unknown): string;
export function validateStringify<T>(input: T | unknown): IValidation<string>;
}</Tabs.Tab> <Tabs.Tab> </Tabs.Tab> <Tabs.Tab> </Tabs.Tab>
Same shape as the parsers — hoist the per-type code once if you stringify the same T from many places:
const stringifyUser = typia.json.createStringify<User>();
const safeStringifyUser = typia.json.createAssertStringify<User>();<Tabs items={["TypeScript Source", "Compiled JavaScript"]}> <Tabs.Tab> </Tabs.Tab> <Tabs.Tab> </Tabs.Tab>
Up to ~200× faster than class-transformer, ~10× faster than native JSON.stringify:
Measured on AMD Ryzen 9 7940HS, Rog Flow x13
A common reaction: "isn't JSON serialization a tiny fraction of request time?"
It's not. Node.js handles most I/O asynchronously, but JSON.stringify is synchronous and runs on the main thread. While it's running, no other request is being routed, no socket is being read, nothing else happens. On a busy server, that synchronous time is the cost you actually pay.
typia.json.stringify cuts that time substantially. The end-to-end request benchmark below shows the difference at server scope (not just the serializer in isolation):
Measured on AMD Ryzen 9 7940HS, Rog Flow x13
- Reading JSON safely →
json.*Parse - Emitting JSON Schema or OpenAPI from
T→json.schemas - Underlying validators —
is,assert,validate
