TypeScript already has typings for fetch that you can reuse:
RequestInfo for the input parameter (you've called it url, but fetch calls it input [MDN, spec], and it may not be a string)
RequestInit for the optional init parameter (you don't seem to be using that in your get)
Response for the response.
So:
class Api {
public get(input: RequestInfo, params = {}): Promise<Response> {
const body = new URLSearchParams(params).toString();
return fetch(input, {method: 'GET', body});
}
}
In a comment you've asked:
how do I allow the user to simply call await api.get().json()?
That's a very different question than a question about types. You'd probably still return Promise<Response>, but you'd implement the first-level then handler within get (I do this anyway, because the fetch API is flawed, encouraging lots of failures to handle errors as I describe here.) So for instance:
class Api {
public async get(input: RequestInfo, params = {}): Promise<Response> {
const body = new URLSearchParams(params).toString();
const response = await fetch(input, {method: 'GET', body});
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
return response;
}
}
Since Response implements Body, it has json() etc. on it. If you wanted, you could return Promise<Body> instead and return .body:
class Api {
public async get(input: RequestInfo, params = {}): Promise<Body> {
const body = new URLSearchParams(params).toString();
const response = await fetch(input, {method: 'GET', body});
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
return response.body;
}
}
...but I don't think that buys you anything.
(input: RequestInfo | URL, init?: RequestInit). This is what I was looking for :)