Sikau

Project: Team workflow · Day 2 · about 40 min

Type the data

Model the API with interfaces and unions, and check unknown JSON with a type guard.

JSON is a promise nobody signed

Data from a server arrives as text. JSON.parse returns any — TypeScript can't know what's inside. Describe the shape you expect, then *check* it at runtime with a type guard, and return a Result instead of throwing, so callers must handle failure.

Types for the café API

type Category = "food" | "drink";

interface MenuItem {
  id: string;
  name: string;
  price: number;
  category: Category;
  vegetarian?: boolean;
}

type Result<T> = { ok: true; value: T } | { ok: false; error: string };

function isMenuItem(x: unknown): x is MenuItem {
  if (typeof x !== "object" || x === null) return false;
  const o = x as Record<string, unknown>;
  return (
    typeof o.id === "string" &&
    typeof o.name === "string" &&
    typeof o.price === "number" &&
    (o.category === "food" || o.category === "drink") &&
    (o.vegetarian === undefined || typeof o.vegetarian === "boolean")
  );
}

function parseMenu(json: string): Result<MenuItem[]> {
  let data: unknown;
  try {
    data = JSON.parse(json);
  } catch {
    return { ok: false, error: "Invalid JSON" };
  }
  if (!Array.isArray(data)) return { ok: false, error: "Expected a list" };
  if (!data.every(isMenuItem)) return { ok: false, error: "Bad menu item" };
  return { ok: true, value: data };
}

The rest of this lesson

  • Writing a type guardexplain
  • Result instead of exceptionsexplain
  • Does it compile?predict
  • Guard resultspredict
  • Parse the menu safelywrite code
  • Badge quizquiz
  • What you builtrecap

Continue this lesson free — run real code in your browser

Continue with Google

See all 5 lessons of Project: Team workflow