use-debounce icon indicating copy to clipboard operation
use-debounce copied to clipboard

Simplify extended useDebouncedCallback function types

Open sarunast opened this issue 2 years ago • 0 comments

The types are failing if the function is used with other generic functions. For example type <Args extends Array<unknown> fails this check.

A minimal example of the failing types that this change would fix:

import type { ActionCreatorWithPreparedPayload } from "@reduxjs/toolkit";
import { useDispatch } from "react-redux";
import { useDebouncedCallback } from "use-debounce";

interface UseFilterUpdaterParams<Args extends Array<unknown>, Payload> {
  updateFunction: ActionCreatorWithPreparedPayload<Args, Payload>;
  DEBOUNCED_HANDLER_MS?: number;
}

const useUpdater = <Args extends Array<unknown>, Payload>({
  updateFunction,
  DEBOUNCED_HANDLER_MS = 0,
}: UseFilterUpdaterParams<Args, Payload>) => {
  const dispatch = useDispatch();

  /**
   * Argument of type '(...props: Args) => void' is not assignable to parameter of type '(...args: any[]) => void'.
   *   Types of parameters 'props' and 'args' are incompatible.
   *     Type 'any[]' is not assignable to type 'Args'.
   *       'any[]' is assignable to the constraint of type 'Args', but 'Args' could be instantiated with a different subtype of constraint 'unknown[]'.(2345)
   */
  const debouncedCallback = useDebouncedCallback((...props: Args) => {
    dispatch(updateFunction(...props));
  }, DEBOUNCED_HANDLER_MS);

  return debouncedCallback;
};

export default useUpdater;

Reproducible example: Typescript playground

sarunast avatar Aug 11 '22 14:08 sarunast