import produce, { Draft } from 'immer' import { useMemo } from 'react' export type WritableDraft = (draft: Draft) => void export function useWarpImmerSetter (setter: (f: WritableDraft) => void) { const set = useMemo(() => { function set> (key: K, value: Draft[K]): void function set (data: Partial): void function set (f: (draft: Draft) => void | T): void function set> (data: any, value?: Draft[K]): void { if (typeof data === 'string') { setter((draft: Draft) => { const key = data as K const v = value draft[key] = v! }) } else if (typeof data === 'function') { const fn = data as (draft: Draft) => void | T setter(draft => fn(draft)) } else if (typeof data === 'object') { setter(pre => produce(pre, (draft: Draft) => { const obj = data as Draft for (const key of Object.keys(obj)) { const k = key as keyof Draft draft[k] = obj[k] } })) } } return set }, [setter]) return set }