Ensure your code treats null, undefined, “omitted”, and “empty” as distinct meanings—especially across serialization boundaries—and encode those meanings explicitly.
Apply these rules:
null meaning “not provided”) into consistent internal representations.?? when omission and empty are different intents: protobuf and decoders may turn an omitted field into []. When intent depends on “provided vs not provided”, decide using length/presence checks, not only nullish coalescing.null vs {} encoding, undefined swallowed by defaults, and “missing repoUrl must not silently fall back”.Example (flag precedence + null normalization):
export function isFrontmatterDisabled(data: Record<string, unknown>): boolean {
return data.disabled === true || (data.disabled === undefined && data.enabled === false)
}
// Normalize model-sent null to omission
function normalizeOptionalString(v: unknown): string | undefined {
return typeof v === "string" ? v : undefined // treat null/undefined/other as omitted
}