type DeferFunction<TArgs extends any[], TReturn> = (...args: TArgs) => TReturn; // useDefer is a function that takes a function and returns a function that // calls the original function and then calls the onComplete function. export function useDefer<TArgs extends any[], TReturn>( onComplete: (...args: TArgs) => void, func: DeferFunction<TArgs, TReturn> ): DeferFunction<TArgs, TReturn> { return (...args: TArgs) => { let result: TReturn; try { result = func(...args); } finally { onComplete(...args); } return result; }; }