Typescript: Typing Your API Requests - Generics Hacks #4
Taric Ov
Posted on June 14, 2023
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.
- 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
- 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 makeunknown
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
}
- 🔥 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
- 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
}
- 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
}
➕…and intellisense is working 🟢
🟢🟢 Check out the full example code in the Typescript playground (try it urself)
🟢🟢 Check out the full example code gist:
Posted on June 14, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 30, 2024