Skip to content

Commit

Permalink
feat: (TS) provide different overloads of useImmerReducer (#108)
Browse files Browse the repository at this point in the history
  • Loading branch information
yifanwww authored Nov 19, 2022
1 parent 332a375 commit 941f27e
Showing 1 changed file with 34 additions and 12 deletions.
46 changes: 34 additions & 12 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import produce, { Draft, nothing, freeze } from "immer";
import { useState, useReducer, useCallback, useMemo, Dispatch } from "react";

export type Reducer<S = any, A = any> = (
draftState: Draft<S>,
action: A
) => void | (S extends undefined ? typeof nothing : S);
export type DraftFunction<S> = (draft: Draft<S>) => void;
export type Updater<S> = (arg: S | DraftFunction<S>) => void;
export type ImmerHook<S> = [S, Updater<S>];

export function useImmer<S = any>(initialValue: S | (() => S)): ImmerHook<S>;

export function useImmer(initialValue: any) {
Expand All @@ -26,16 +23,41 @@ export function useImmer(initialValue: any) {
];
}

export function useImmerReducer<S = any, A = any>(
reducer: Reducer<S, A>,
// Provides different overloads of `useImmerReducer` similar to `useReducer` from `@types/react`.

export type ImmerReducer<S, A> = (
draftState: Draft<S>,
action: A
) => void | (S extends undefined ? typeof nothing : S);

/**
* @deprecated Use `ImmerReducer` instead since there is already a `Reducer` type in `@types/react`.
*/
export type Reducer<S = any, A = any> = ImmerReducer<S, A>;

export function useImmerReducer<S, A, I>(
reducer: ImmerReducer<S, A>,
initializerArg: S & I,
initializer: (arg: S & I) => S
): [S, Dispatch<A>];

export function useImmerReducer<S, A, I>(
reducer: ImmerReducer<S, A>,
initializerArg: I,
initializer: (arg: I) => S
): [S, Dispatch<A>];

export function useImmerReducer<S, A>(
reducer: ImmerReducer<S, A>,
initialState: S,
initialAction?: (initial: any) => S
initializer?: undefined
): [S, Dispatch<A>];
export function useImmerReducer(
reducer: any,
initialState: any,
initialAction: any

export function useImmerReducer<S, A, I>(
reducer: ImmerReducer<S, A>,
initializerArg: S & I,
initializer?: (arg: S & I) => S
) {
const cachedReducer = useMemo(() => produce(reducer), [reducer]);
return useReducer(cachedReducer, initialState as any, initialAction);
return useReducer(cachedReducer, initializerArg as any, initializer as any);
}

0 comments on commit 941f27e

Please sign in to comment.