Strongly Types useDynamicCallback

Viewed 139

I am using ag-grid with React and would like to use useDynamicCallback function. However, the given example is a js one and I would like to use it in typescript.

Below is what they have:

function useDynamicCallback(callback) {
    const ref = useRef();
    ref.current = callback;
    return useCallback((...args) => ref.current.apply(this, args), []);
}

Below is how I added types to escape ts-lint errors:

const useDynamicCallback = (callback: any) => {
    const ref = useRef();
    ref.current = callback;
    return useCallback((...args) => (ref as any).current.apply(this, args), []);
};

Can someone help me with a strongly typed function so I can get away with any, if possible? Thanks.

2 Answers

It is not necessary to use this in the arrow function because arrow functions establish "this" based on the scope the Arrow function is defined within, just call the callback with the parameter directly. See call, apply and bind

But if you insist to use it, here is the type-safe version:

import { useRef, useCallback } from 'react';

type AnyFunction = (...args: any) => any;

function useDynamicCallback(this: ThisParameterType<AnyFunction>, callback: AnyFunction) {
  const ref = useRef<AnyFunction>();
  ref.current = callback;
  return useCallback((...args: Parameters<AnyFunction>) => ref.current?.apply(this, args), []);
}

TypeScript Playground

function useDynamicCallback<T extends (...args: any[]) => any>(callback: T): T {
  const ref = React.useRef(callback);
  ref.current = callback;
  return React.useCallback((...args: unknown[]) => {
    // eslint-disable-next-line @typescript-eslint/no-unsafe-return
    return ref.current.apply(null, args);
  }, []) as T;
}

enter image description here

enter image description here

Related