i wrote a custom hook to interact with the sessionStorage in React. Currently I don't like that I can just arbitrarily write any key-value pair in there. For testing and debugging purposes I would like to introduce a form of TypeSafety and I was thinking about maybe using a Union Type rather then the Generic.
I basically want to achieve two goals.
Does anyone have any idea how you would go about implementing these sort of checks in Typescript. Any help is appreciated.
export function useSessionStorage<T>(key: string, initialValue: T) {
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = window.sessionStorage.getItem(key);// Parse stored json or if none return initialValue
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.log(error);
return initialValue;
}
});
const setValue = (value: T | ((val: T) => T)) => {
try {
const valueToStore =
value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
window.sessionStorage.setItem(key, JSON.stringify(valueToStore));
} catch (error) {
console.error(error);
}
};
return [storedValue, setValue] as const;
}
In case someone stumbles across this question, I ended up finding how this is implemented in Typescript. You can achieve the desired effect by the use of the typeof operator on the generic.
basically you first define a interface or type:
type Allowed = {
item1: string
item2: boolean
item3: number
}
Then you can modify the function using the keyof operator
function useSessionStorage<T extends keyof Allowed>(key: T, initialValue: Allowed[T]){
{...}
}
the use of key of is better described here: https://www.typescriptlang.org/docs/handbook/advanced-types.html.
Hope this helps other people that might be struggling with this.