Zod SafeParse Error Formatting

Validate untrusted payloads with Zod safeParse, aggregate every issue with paths, and flatten errors into field-keyed message maps.

TypescriptData Integrity

Code

snippet
import { z } from 'zod';

const PayloadSchema = z.object({
  email: z.string().email(),
  age: z.number().int().min(18).max(120),
  tags: z.array(z.string().min(1)).max(5),
  role: z.enum(['admin', 'editor', 'viewer']).default('viewer'),
});

type Payload = z.infer<typeof PayloadSchema>;

function validate(raw: unknown):
  { ok: true; value: Payload } | { ok: false; fields: Record<string, string> } {
  const result = PayloadSchema.safeParse(raw);
  if (result.success) return { ok: true, value: result.data };

  const fields: Record<string, string> = {};
  for (const issue of result.error.issues) {
    const key = issue.path.join('.') || '_root';
    fields[key] ??= issue.message;
  }
  return { ok: false, fields };
}

const good = validate({ email: '[email protected]', age: 30, tags: ['a'] });
const bad = validate({ email: 'nope', age: 15, tags: [] });

console.log(good.ok, bad.ok ? '' : JSON.stringify(bad.fields));