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
2. This is the function where we request data…
Promise<unknown>
leverage the use of one of the primitive types in Typescriptunknown
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 checkingunknown
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
}
3. 🔥 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
4. 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
}
5. 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: