When dealing with optional, nullable, or possibly-missing values, handle them explicitly and avoid redundant or misleading fallback patterns:
undefined is a no-op, so { ...args?.header } is sufficient; { ...(args?.header ?? {}) } is redundant.// Bad: options.all/options.dot already resolved before destructuring, can override caller's input
const { all = options?.all ?? false, dot = options?.dot ?? false } = options
// Good: single point of truth for defaults
export const parseBody = async (
request: HonoRequest | Request,
options: ParseBodyOptions = {}
) => {
const { all = false, dot = false } = options
...
}
?? only triggers on null/undefined, || also triggers on falsy values like '' or false. If an empty string or false is a meaningful, distinct value (e.g. “no header name” vs “use default header name”), handle it explicitly instead of relying on ??:
// headerName === '' means "disable the feature", which `??` won't catch
let requestId = headerName ? c.req.header(headerName) : undefined
in check or a type-guard function) over chained optional access, which can silently resolve to undefined even when the property exists under a different shape:
// Bad: silently undefined for APIGatewayProxyEventV2
method: event.httpMethod ?? event.requestContext.http?.httpMethod
// Good: explicit discrimination between event shapes
const method = 'httpMethod' in event ? event.httpMethod : event.requestContext.http.method
!) to silence the type checker; prefer explicit null checks or restructuring the logic so TypeScript can narrow the type on its own.'' instead of mixing undefined/null/'') so the function’s return type stays predictable (e.g. string instead of string | undefined) and callers don’t need extra null checks.Applying these practices prevents subtle bugs from incorrect fallback logic, keeps nullable/optional handling intentional, and reduces the need for non-null assertions and type casts.