Skip to content
GreenSnippets

Parse JSON into a typed value with a guard

Safely turn unknown JSON into a typed result by validating its shape instead of casting.

TypeScript
interface Product {
  id: number;
  name: string;
  tags: string[];
}

function isProduct(value: unknown): value is Product {
  if (typeof value !== "object" || value === null) return false;
  const v = value as Record<string, unknown>;
  return (
    typeof v.id === "number" &&
    typeof v.name === "string" &&
    Array.isArray(v.tags) &&
    v.tags.every((t) => typeof t === "string")
  );
}

function parseJson<T>(text: string, guard: (value: unknown) => value is T): T | null {
  try {
    const data: unknown = JSON.parse(text);
    return guard(data) ? data : null;
  } catch {
    return null;
  }
}

Example / expected output

Output
const product = parseJson('{"id":1,"name":"Pen","tags":["office"]}', isProduct);
// Product | null

How it works

JSON.parse returns any, which silently turns off type checking. Parse into unknown and run a type guard; only then does the compiler treat the value as your type. For larger schemas consider a validation library, but this pattern needs no dependencies.