Alexander
Alexander

Reputation: 81

Preserve method signature in simple decorator

Maybe someone can advise, I implemeted a simple decorator, that accepts method, adds some logic and returns back the method with the same signature.

type Method = (...args: any[]) => Promise<any>

 const useBusy = <T extends Method>(method: T): [boolean, T] => {
  const [isBusy, setIsBusy] = useState(false);
  const wrappedMethod = async (...args: any[]) => {
    setIsBusy(true);
    const result = await method.apply(this, args);
    setIsBusy(false)

    return result;
  }

  return [isBusy, wrappedMethod as T];
}

export default useBusy;

Is it possible to do the same but instead of array return object {IsBusy, method}? But I want to preserve name of passed method, for example if I do the following:

const {isBusy, myMethod} = useBusy(myMethod) I want typescript checks the response names, only isBusy and myMethod should be allowed.

Is it possible?

Upvotes: 0

Views: 27

Answers (1)

Tiberiu Maran
Tiberiu Maran

Reputation: 2173

You can't bind to the name of the passed object. What you can do is get an object as input, and output an extended version of that object as output.

const useBusy = <T extends { [k in keyof T]: Method }>(methodObj: T): T & { isBusy: boolean } => {
 ...
}

And then you can do:

const busy = useBusy({myMethod});
const isBusy = busy.isBusy;
const myBusyMethod = busy.myMethod;

Playground

Upvotes: 1

Related Questions