type AnyFunction = (...args: any[]) => any;
type PatchFunction<T, K extends keyof T> = (this: T, original: T[K] extends AnyFunction ? T[K] : never, ...args: Parameters<T[K] extends AnyFunction ? T[K] : never>) => ReturnType<T[K] extends AnyFunction ? T[K] : never>;
/**
 * Patches a method of an object by replacing it with a new implementation while preserving the original functionality.
 *
 * @param target - The object containing the method to be patched
 * @param method - The name of the method to patch
 * @param patchFn - The new implementation that will replace the original method. Receives the original method as first parameter.
 * @throws {TypeError} If the method doesn't exist or is already patched
 */
declare function patch<T extends object, K extends keyof T>(target: T, method: K, patchFn: PatchFunction<T, K>): void;

/**
 * Unpatches a method, restoring the original method to the object.
 *
 * @param target — The target object containing the method.
 * @param method — The method to be unpatched.
 */
declare function unpatch<T extends object, K extends keyof T>(target: T, method: K): void;

export { patch, unpatch };
