Prior Issues
#1002 reported the same default on the runtime side and was fixed in
17.0.1. The result type was never updated to match, and has had its current shape since v17.0.0
(7bcc385).
What is the current behavior?
useLocalStorageValue and useSessionStorageValue type value as Type | undefined even when initializeWithValue
is left at its documented default of true — that is, when the hook does read the storage during the first render and
can never hand back undefined.
Every call site is forced into a null check or a non-null assertion that cannot fire.
Steps to Reproduce
npm install @react-hookz/web@26.1.0 react@19 react-dom@19 @types/react@19 typescript@5.9
- Use
tsconfig.json with "strict": true, "module": "NodeNext", "moduleResolution": "NodeNext",
"lib": ["ESNext", "DOM"]
- Create
repro.ts:
import {useSessionStorageValue, useLocalStorageValue} from '@react-hookz/web';
// A `defaultValue` is set and `initializeWithValue` is left at its default.
export function useName(): string {
const {value} = useSessionStorageValue('name', {defaultValue: 'anonymous'});
return value;
}
// No options at all, `Type` given explicitly.
export function useToken(): string {
return useLocalStorageValue<string>('token').value;
}
- Run
tsc --noEmit
Reproducible at will. Both calls fail:
repro.ts(6,2): error TS2322: Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.
repro.ts(11,2): error TS2322: Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.
The runtime disagrees with both: src/useStorageValue/index.dom.test.ts already asserts that the first render carries
the stored value unless initializeWithValue: false is passed.
What is the expected behavior?
value is string in both cases. undefined belongs in the type only when the first read is actually deferred —
{initializeWithValue: false}, or a flag whose value is not known at compile time.
Environment Details
@react-hookz/web version: 26.1.0
react version: 19.2
react-dom version: 19.2
typescript version: 5.9 (also reproduced with 7.0.2)
- OS: macOS (darwin 25.5.0)
- Browser: n/a, type-level only
- Did this work in previous versions? No. Present since
v17.0.0.
Prior Issues
#1002 reported the same default on the runtime side and was fixed in
17.0.1. The result type was never updated to match, and has had its current shape sincev17.0.0(7bcc385).
What is the current behavior?
useLocalStorageValueanduseSessionStorageValuetypevalueasType | undefinedeven wheninitializeWithValueis left at its documented default of
true— that is, when the hook does read the storage during the first render andcan never hand back
undefined.Every call site is forced into a null check or a non-null assertion that cannot fire.
Steps to Reproduce
npm install @react-hookz/web@26.1.0 react@19 react-dom@19 @types/react@19 typescript@5.9tsconfig.jsonwith"strict": true,"module": "NodeNext","moduleResolution": "NodeNext","lib": ["ESNext", "DOM"]repro.ts:tsc --noEmitReproducible at will. Both calls fail:
The runtime disagrees with both:
src/useStorageValue/index.dom.test.tsalready asserts that the first render carriesthe stored value unless
initializeWithValue: falseis passed.What is the expected behavior?
valueisstringin both cases.undefinedbelongs in the type only when the first read is actually deferred —{initializeWithValue: false}, or a flag whose value is not known at compile time.Environment Details
@react-hookz/webversion: 26.1.0reactversion: 19.2react-domversion: 19.2typescriptversion: 5.9 (also reproduced with 7.0.2)v17.0.0.