Skip to content

Commit 25e8352

Browse files
committed
fixup! client: Add some type annotations
1 parent 132ecdf commit 25e8352

File tree

1 file changed

+45
-24
lines changed

1 file changed

+45
-24
lines changed

client/js/helpers/ajax.ts

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,28 @@ type Headers = {
88
};
99

1010
type FetchOptions = {
11-
body?: string;
11+
body?: BodyInit | null;
1212
method?: 'GET' | 'POST' | 'DELETE';
1313
headers?: Headers;
1414
abortController?: AbortController;
1515
timeout?: number;
1616
failOnHttpErrors?: boolean;
17+
signal?: AbortSignal;
1718
};
1819

20+
interface Fetch {
21+
(url: RequestInfo | URL, opts?: RequestInit): Promise<Response>;
22+
}
23+
24+
type AbortableFetchResult = {
25+
controller: AbortController;
26+
promise: Promise<Response>;
27+
};
28+
29+
interface AbortableFetch {
30+
(url: RequestInfo | URL, opts?: FetchOptions): AbortableFetchResult;
31+
}
32+
1933
/**
2034
* Passing this function as a Promise handler will make the promise fail when the predicate is not true.
2135
*/
@@ -91,9 +105,8 @@ export const liftToPromiseField =
91105
* Wrapper for fetch that makes it cancellable using AbortController.
92106
* @return {controller: AbortController, promise: Promise}
93107
*/
94-
export const makeAbortableFetch =
95-
(fetch) =>
96-
(url: string, opts: FetchOptions = {}) => {
108+
export function makeAbortableFetch(fetch: Fetch): AbortableFetch {
109+
return (url: string, opts: FetchOptions = {}) => {
97110
const controller = opts.abortController || new AbortController();
98111
const promise = fetch(url, {
99112
signal: controller.signal,
@@ -102,14 +115,16 @@ export const makeAbortableFetch =
102115

103116
return { controller, promise };
104117
};
118+
}
105119

106120
/**
107121
* Wrapper for abortable fetch that adds timeout support.
108-
* @return {controller: AbortController, promise: Promise}
122+
* @return
109123
*/
110-
export const makeFetchWithTimeout =
111-
(abortableFetch) =>
112-
(url: string, opts: FetchOptions = {}) => {
124+
export function makeFetchWithTimeout(
125+
abortableFetch: AbortableFetch,
126+
): AbortableFetch {
127+
return (url: string, opts: FetchOptions = {}): AbortableFetchResult => {
113128
// offline db consistency requires ajax calls to fail reliably,
114129
// so we enforce a default timeout on ajax calls
115130
const { timeout = 60000, ...rest } = opts;
@@ -119,7 +134,7 @@ export const makeFetchWithTimeout =
119134
const newPromise = promise.catch((error) => {
120135
// Change error name in case of time out so that we can
121136
// distinguish it from explicit abort.
122-
if (error.name === 'AbortError' && promise.timedOut) {
137+
if (error.name === 'AbortError' && 'timedOut' in promise) {
123138
error = new TimeoutError(
124139
`Request timed out after ${timeout / 1000} seconds`,
125140
);
@@ -129,7 +144,7 @@ export const makeFetchWithTimeout =
129144
});
130145

131146
setTimeout(() => {
132-
promise.timedOut = true;
147+
(promise as { timedOut?: boolean }).timedOut = true;
133148
controller.abort();
134149
}, timeout);
135150

@@ -138,14 +153,13 @@ export const makeFetchWithTimeout =
138153

139154
return { controller, promise };
140155
};
156+
}
141157

142158
/**
143159
* Wrapper for fetch that makes it fail on HTTP errors.
144-
* @return Promise
145160
*/
146-
export const makeFetchFailOnHttpErrors =
147-
(fetch) =>
148-
(url: string, opts: FetchOptions = {}) => {
161+
export function makeFetchFailOnHttpErrors(fetch: Fetch): Fetch {
162+
return (url: string, opts: FetchOptions = {}): Promise<Response> => {
149163
const { failOnHttpErrors = true, ...rest } = opts;
150164
const promise = fetch(url, rest);
151165

@@ -155,13 +169,13 @@ export const makeFetchFailOnHttpErrors =
155169

156170
return promise;
157171
};
172+
}
158173

159174
/**
160175
* Wrapper for fetch that converts URLSearchParams body of GET requests to query string.
161176
*/
162-
export const makeFetchSupportGetBody =
163-
(fetch) =>
164-
(url: string, opts: FetchOptions = {}) => {
177+
export function makeFetchSupportGetBody(fetch: Fetch): Fetch {
178+
return (url: string, opts: FetchOptions = {}) => {
165179
const { body, method, ...rest } = opts;
166180

167181
let newUrl = url;
@@ -182,13 +196,13 @@ export const makeFetchSupportGetBody =
182196

183197
return fetch(newUrl, newOpts);
184198
};
199+
}
185200

186201
/**
187202
* Cancellable fetch with timeout support that rejects on HTTP errors.
188203
* In such case, the `response` will be member of the Error object.
189-
* @return {controller: AbortController, promise: Promise}
190204
*/
191-
export const fetch = pipe(
205+
export const fetch: AbortableFetch = pipe(
192206
// Same as jQuery.ajax
193207
option('credentials', 'same-origin'),
194208
header('X-Requested-With', 'XMLHttpRequest'),
@@ -199,19 +213,26 @@ export const fetch = pipe(
199213
makeFetchWithTimeout,
200214
)(window.fetch);
201215

202-
export const get = liftToPromiseField(option('method', 'GET'))(fetch);
216+
export const get: AbortableFetch = liftToPromiseField(option('method', 'GET'))(
217+
fetch,
218+
);
203219

204-
export const post = liftToPromiseField(option('method', 'POST'))(fetch);
220+
export const post: AbortableFetch = liftToPromiseField(
221+
option('method', 'POST'),
222+
)(fetch);
205223

206-
export const delete_ = liftToPromiseField(option('method', 'DELETE'))(fetch);
224+
export const delete_: AbortableFetch = liftToPromiseField(
225+
option('method', 'DELETE'),
226+
)(fetch);
207227

208228
/**
209229
* Using URLSearchParams directly handles dictionaries inconveniently.
210230
* For example, it joins arrays with commas or includes undefined keys.
211231
*/
212-
export const makeSearchParams = (data) =>
213-
new URLSearchParams(
232+
export function makeSearchParams(data: object): URLSearchParams {
233+
return new URLSearchParams(
214234
formurlencoded(data, {
215235
ignorenull: true,
216236
}),
217237
);
238+
}

0 commit comments

Comments
 (0)