Notes on typing JSON.

Short essays on the decisions behind the inferred types this site produces. Opinionated, specific, and occasionally wrong.

  1. 01

    Optional[T] or T | None: pick one

    A field that is always sent but sometimes null is not the same as a field that is sometimes missing. Python lets you collapse both into Optional[T] = None and pretend they are the same. They are not.

    · 6 min read

  2. 02

    Pydantic vs dataclasses: when the runtime cost earns its keep

    A dataclass is free at runtime. A Pydantic model is not — it actually validates. The question is where the validation cost buys you something, and where it is insurance on a risk that does not exist.

    · 6 min read

  3. 03

    Nullable or optional: pick one

    A nullable field and a sometimes-absent field are different promises. Collapsing them into one optional type loses the signal the server was trying to send.

    · 5 min read

  4. 04

    When string is a lie

    A field that is always "customer" is not a string. It is a discriminant. Widening it to string removes the reason the type existed.

    · 5 min read

  5. 05

    Zod vs types: when the runtime cost earns its keep

    Zod ships 14 KB of JavaScript and spends CPU on every parse. The question is not whether that is acceptable, but where the spend actually buys you something.

    · 6 min read

  6. 06

    Go struct tags: explicit beats clever

    The explicit per-field json tag looks verbose until you need to audit, grep, or change it. Then it becomes the reason the struct is still readable.

    · 6 min read

  7. 07

    Why we do not re-infer from JSON Schema

    A schema is what they promised. A sample is what they sent. Both are useful. Conflating them hides the places they disagree, which are the places that matter.

    · 5 min read