DEV Community

Cover image for Typescript: Typing Your API Requests - Generics Hacks #4
Taric Ov
Taric Ov

Posted on

Typescript: Typing Your API Requests - Generics Hacks #4

Are you ready to take your REST API requests to the next level? Buckle up, because… Ah! 😑 why go boring? while i can call u guyzzzzz 🤣

Btw, do you know? Along this short series, TypeScript and typing cases had come to a closer place to us, and are about to become that handy that do a lot of magic by a few tricks! 🙂

This is not generics-related tut but it's extending on the last Generics Hacks article.. we will use TypeScript generics to provide a type-safe response coming from REST API requests whatever they were.


TypeScript's UNKNOWN = The New Way of Knowing Things. 

We'll be using fetch API in this example, and will be using dummyjson.com to fetch dummy data for demonstration:

Notes will precede code blocks … you can check out the code first and then read the notes.

  1. Setting some variables for making API requests.

// STEP 1
// setting variables
const url:string = "https://dummyjson.com";
const endPoint: string = "/users"
// u could use /posts or /products for other data types

Enter fullscreen mode Exit fullscreen mode
  1. This is the function where we request data…
  • Promise leverage the use of one of the primitive types in Typescript unknown 

  • unknown is way safer than any that mist typing and make 

  • unknown is so useful for APIs when you need to perform type checking before you use them.

  • In contrast to any which means disable type checking unknown is a Typescript real and capable type, it's just
    the least effective among the more-specific others.

  • The real power of unknown typing value is that you can use type guards to narrow the type and get more accurate type-checking on narrowed types.


// STEP 2
async function GetAllItems(
  url: string, endpoint: string
): Promise<unknown> {
  const response = await fetch(url + endpoint);
  const json = await response.json();
  return json.users 
}

Enter fullscreen mode Exit fullscreen mode
  1. 🔥 A TRICK 🔥: now we declare an example user object w/ some/all properties. We will use that obj. to prototype that as our new base type User for that API call result

// STEP 3
const userExample = {
  id: '',
  firstName: '',
  lastName: '',
}
type User = typeof userExample

Enter fullscreen mode Exit fullscreen mode
  1. Here we goooo.. one more step before sending our request:
  • We are making a type-checker function based on the base-type User 

  • The checker will take a user as a param to check on its type

  • And will return the result narrowed using the Type-gaurd operator is

  • So if user passes the checker and evaluates to => true

  • That will enforce our typing for intellisense and type-safe use for all users


// STEP 4
function isUser(user: any): user is User {
  // defaulting to false for effective checking
  let checking = false
  // iterating over keys from the `userExample` as they r the same keys for `User`
  for(const t of Object.keys(userExample)){
   checking = t in user
    if(!checking)
      return false
  }
  // if only one key evaluetes false 👆 user fails the test
  // otherwise it passes and return true 👇 and pass the success status to all the array result of users
  return checking
}

Enter fullscreen mode Exit fullscreen mode
  1. Now we call our API endpoint and return:

// STEP 5
SendReq()
async function SendReq(
): Promise<User | null> {
  const allUsers:any = await GetAllItems(url, endPoint) // allUsers as `any` here to bypass the linter and we r about to check the type ourselves
  const user = allUsers[0] 
  if (user && isUser(user)) {
    console.log(user)
    // now user is typed and can be used safely 
    return allUsers; 
  }
  return null; // in case isUser(user) checking fails
}

Enter fullscreen mode Exit fullscreen mode

…and intellisense is working 🟢

Image description

🟢🟢 Check out the full example code in the Typescript playground (try it urself)

🟢🟢 Check out the full example code gist:

Top comments (0)