When handling query/mutation results, treat undefined (and null) as semantically distinct and enforce that distinction in both runtime checks and TypeScript types.
Coding standards
null, false, "") are not misclassified.value !== undefined / value === undefinedundefined where the API contract says it can’t.
!) that hide cancelled/empty states.undefined.
undefined/optional handling over {}-style fallbacks that widen unions.Example
// 1) Presence checks: don’t use truthy
const data = query.state.data
const hasData = data !== undefined // null/false/"" are valid
// 2) Imperative fetch contract: never resolve undefined
async function fetchQueryImperative() {
if (initialFetchCancelled) {
throw new Error('Cancelled')
}
// safe: data is guaranteed by control flow
return data
}
// 3) Skip token: don’t return undefined as “success data”
if (queryFn === skipToken) {
return Promise.reject(
new Error('Attempted to invoke queryFn when set to skipToken')
)
}
Applying these rules prevents subtle SSR/hydration mismatches, avoids incorrect cache restore decisions, and keeps null/undefined behavior predictable across the codebase.
Enter the URL of a public GitHub repository