Null vs Undefined
The distinction between null and undefined is simple:
null → the property exists, and is explicitly empty
undefined → the property does not exist, or is unknown
Yet in practice, we default to undefined even when we clearly mean null.
If a field is known to exist (for example, it’s part of a type), then an empty value should be null, not undefined.
Payloads: Intent Matters
Consider an update payload:
{ "dob": null }
This clearly states: clear the date of birth.
{ "dob": undefined }
This states: nothing is known or being said about dob.
These are not the same instruction. One is an explicit command. The other is silence.
Queries: Absence vs Irrelevance
The same distinction applies to searching and filtering:
siteId = null → find entities that have no site relationship
siteId = undefined (or omitted entirely) → site should not affect the search
Again: one is a constraint, the other is the absence of a constraint.
The Cost of Ignoring This
Unfortunately, much of the ecosystem disagrees. Libraries, APIs, and even AIs routinely collapse these concepts. The result is code littered with defensive checks, ambiguous payloads, and brittle logic.
Worse still, coding defensively against incorrect type usage is painful—and usually avoidable.
Clear intent leads to simpler systems. And clear intent starts with using the right value.