Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fetch written in Typescript

I want to write a typescript wrapper to do a type safe fetch with Typescript. I've been googling around and the best source I've found is a this thread from 2016. It seemed to help the people in 2016, but now I don't get the snippet to work.

The following makes the TS Linter complain ([ts] Expected 0 type arguments, but got 1.):

response.json<T>()

So according to according to this thread I changed it to the following

data => data as T

Neither of the options above works, as both calls returns undefined. If a source such as this is used, I expect to be able to use {name: string, username: string}, like so:

api<{ name: string; username: string }>('https://jsonplaceholder.typicode.com/users')

The following then clause:

 .then(({ name, username })

A thorough walk through on how to create a wrapper function for doing type safe fetch calls would be appreciated.

EDIT

Adding a more complete snippet as requested

api<T>(url: string): Promise<T> {
  return fetch(url)
    .then(response => {
      if (!response.ok) {
        throw new Error(response.statusText);
      }
      return response.json().then(data => data as T);
    })
    .catch((error: Error) => {
      throw error;
    });
}

// consumer
this.api<{ name: string; username: string }>("https://jsonplaceholder.typicode.com/users/")
  .then(({ name, username }) => {
    console.log(name, username);
  })
  .catch(error => {
    console.error(error);
  });
like image 493
Max Avatar asked May 01 '26 04:05

Max


1 Answers

The Typescript part is fine. Using as T in the json method should work fine.

The problem is your json contains an array, not a single object. So the rest of the code would work if you wrote return response.json().then(data => data[0]); selecting just one element.

You probably want the whole array though, in which case you need to change the consumer to pass an array of the expected type:

this.api<Array<{ name: string; username: string }>>("https://jsonplaceholder.typicode.com/users/")
    .then(data  => {
       data.forEach(({ name, username }) => console.log(name, username))
    })
    .catch(error => {
      console.error(error);
    });
like image 162
Titian Cernicova-Dragomir Avatar answered May 02 '26 20:05

Titian Cernicova-Dragomir