import { Dispatch, SetStateAction, useCallback, useMemo } from "react"; export function makePartialSetter(fullSetter: Dispatch>, key: K): Dispatch> { return (newValueOrCallback: T[K] | ((newValue: T[K]) => T[K])) => { fullSetter(oldFullValue => { const newValue = (typeof newValueOrCallback === 'function') ? (newValueOrCallback as (newValue: T[K]) => T[K])(oldFullValue[key] as T[K]) : newValueOrCallback as T[K]; if (newValue === oldFullValue[key]) { return oldFullValue; } else { return { ...oldFullValue, [key]: newValue, } } }) }; } export type Setters = { [K in keyof T as `set${Capitalize>}`]: Dispatch>; } export function makeAllSetters( fullSetter: Dispatch>, keys: (keyof T)[], ): Setters { // @ts-ignore return useMemo(() => { console.log('creating setters for App'); // @ts-ignore return Object.fromEntries(keys.map((key: string) => { return [`set${key.charAt(0).toUpperCase()}${key.slice(1)}`, makePartialSetter(fullSetter, key)]; })); }, [fullSetter]); }