HookResult
The shape every action resolves to.
Every action in this package resolves to a HookResult. Actions never throw.
type HookResult<T> =
| ({ success: true } & T)
| { success: false; error: string; code: string | null; cause: unknown };import type { HookResult } from '@timonwa/firebase-hooks';On success
success: true plus whatever that action returns. Sign-ins add user and credential, where credential is Firebase's raw UserCredential — nothing is withheld or reshaped.
const result = await login(email, password);
if (result.success) {
result.user; // User
result.credential; // UserCredential
}Actions with nothing to return resolve to plain { success: true }.
On failure
| Field | Type | What it is |
|---|---|---|
error | string | The message for rendering — raw by default |
code | string | null | Firebase's own code, e.g. "auth/invalid-credential" |
cause | unknown | The complete untouched error |
code and cause are always Firebase's own. Only error is ever processed, and only if you opt in — see Error handling.
Narrowing
success is a discriminant, so TypeScript narrows on it:
const result = await login(email, password);
if (!result.success) {
result.code; // string | null
return;
}
result.user; // User — narrowed, no optional chaining neededAsyncStatus
HookResult covers actions you call. A hook that acts on mount reports a status instead, and they all use one vocabulary:
type AsyncStatus = 'pending' | 'error' | 'success';There is no idle state — the work starts before you can render, so pending is where it begins. useVerifyEmail reports it as VerifyEmailStatus, an alias of this.
Actions you call get one more state, because nothing runs until you call them:
type ActionStatus = 'idle' | AsyncStatus;Every action hook returns status: ActionStatus with isIdle, isPending, isSuccess and isError derived from it, plus reset(). Two vocabularies rather than one is deliberate — the same split TanStack Query makes between a query's status and a mutation's.
Render the three branches and you've handled every case:
if (status === 'pending') return <Spinner />;
if (status === 'error') return <ErrorState message={error} />;
return <Success />;Related types
HookErrorOptions — the formatErrorMessage option every hook accepts.
HookErrorContext — what the provider's onError observer receives: { action, code, message }.