Callback 추론 - ChoDragon9/posts GitHub Wiki

export const debounce = <
  Prop,
  Callback extends PropCallback | VoidCallback,
  VoidCallback = () => void,
  PropCallback = (prop: Prop) => void,
>(
  callback: Callback extends (prop: Prop) => void
    ? (prop: Prop) => void
    : () => void,
  ms = 0,
) => {
  let timer: null | ReturnType<typeof setTimeout> = null;

  return (...props: Prop[]) => {
    timer && clearTimeout(timer);

    timer = setTimeout(() => {
      callback(props[0]);
    }, ms);
  };
};


debounce(() => {
  console.log("empty");
}, 100);
debounce((num: number) => {
  console.log(num);
}, 100);
debounce(({ num, str }: { num: number; str: string }) => {
  console.log(num, str);
}, 100);

// TS2345: Argument of type '(num: number, str: string) => void' is not assignable to parameter of type '(props: number) => void'
debounce((num: number, str: string) => {
  console.log(num, str);
}, 100);