// Allow to cancel request for window.fetch() export interface CancelablePromise extends Promise { then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): CancelablePromise; catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): CancelablePromise; finally(onfinally?: (() => void) | undefined | null): CancelablePromise; cancel(): void; } interface WrappingFunction { (result: Promise): CancelablePromise; (result: T): T; } export function cancelableFetch(reqInfo: RequestInfo, reqInit: RequestInit = {}) { const abortController = new AbortController(); const signal = abortController.signal; const cancel = abortController.abort.bind(abortController); const wrapResult: WrappingFunction = function (result: any) { if (result instanceof Promise) { const promise: CancelablePromise = result as any; promise.then = function (onfulfilled, onrejected) { const data = Object.getPrototypeOf(this).then.call(this, onfulfilled, onrejected); return wrapResult(data); } promise.cancel = cancel; } return result; } const req = fetch(reqInfo, { ...reqInit, signal }); return wrapResult(req); }