When a value can legitimately be undefined/null at runtime, make sure both the type signature and the code reflect that, and access it safely:
undefined (e.g. a missing route match, a header lookup, a route param), its type must include | undefined (or | null) rather than being asserted as non-nullable. Fix the types instead of hiding the gap with a non-null assertion (!).?., ??) over non-null assertions or || when a value may legitimately be an empty string, 0, or false (which || would incorrectly treat as missing).// Avoid:
const options: Options = { all: false, dot: false }
const parseBody = (opts: Options = options) => { ... }
// Prefer:
const parseBody = (opts?: Options) => {
const all = opts?.all ?? false
const dot = opts?.dot ?? false
}
'prop' in event rather than chaining ?. across incompatible shapes, since optional chaining can silently resolve to undefined even when the correct sibling property exists under a different key.event.queryStringParameters before calling Object.entries on it, or check event.headers before iterating), instead of assuming they are always present.undefined as a sentinel/cache value when undefined is also a valid resolved value (e.g. caching a promise result); use a distinct marker so legitimate undefined results aren’t mistaken for “not yet set”.Applying these practices keeps types trustworthy, avoids runtime crashes from unchecked optional access, and prevents subtle bugs caused by treating falsy-but-valid values (empty string, false) as missing.