How to Use fetch with TypeScript
Responses (6)
There's a typo in the code below: Promise<TReponse> should be Promise<TResponse>
The main problem with fetch
function is that it isn't a generic function. This makes it harder to type response data without writing additional wrappers.
type User = {
name: string;
age: number;
}
// This won't work.
fetch<User>('/api/user/42').then(user => {
// `user` will be of `unknown` type.
})
We can create a wrapper-module to avoid this problem.
Wrapper Module#
Let's create a function request
that will handle network requests:
// Make the `request` function generic
// to specify the return data type:
function request<TResponse>(
url: string,
// `RequestInit` is a type for configuring
// a `fetch` request. By default, an empty object.
config: RequestInit = {}
// This function is async, it will return a Promise:
): Promise<TResponse> {
// Inside, we call the `fetch` function with
// a URL and config given:
return fetch(url, config)
// When got a response call a `json` method on it
.then((response) => response.json())
// and return the result data.
.then((data) => data as TResponse);
// We also can use some post-response
// data-transformations in the last `then` clause.
}
Now we can call this function as we would call fetch
:
request<User>('/api/users/42').then(user => {
// Now, however, a `user` variable has the `User` type.
})
Or, since it is an async
function we can use await
:
const user = await request<User>('/api/users/42');
Error Handling#
Right now the request
function doesn't handle errors. To solve that we have 2 options:
Handle errors inside of the
request
function;Let another module handle errors.
There are no obligatory rules for this but Single Responsibility Principle tells us not to mix those concerns in a single function.
However, we will take a look at both ways. The first one is to handle errors inside of the request
function:
function request<TResponse>(
url: string,
config: RequestInit
): Promise<TResponse> {
Shouldn't the response error (response.ok) still be handled inside the request function?