Type-safe API response handling helps you catch mistakes early by making sure the data you get from an API matches what you expect. This keeps your program safe and easier to fix.
Type-safe API response handling in Typescript
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
async function fetchData<T>(url: string): Promise<ApiResponse<T>> {
const response = await fetch(url);
if (!response.ok) {
throw new Error('Network error');
}
const json = await response.json();
return json as ApiResponse<T>;
}Use interface or type to define the expected shape of the API response.
Use generics <T> to make the function flexible for different data types.
User object.interface User {
id: number;
name: string;
}
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
async function fetchUser(): Promise<ApiResponse<User>> {
const response = await fetch('https://api.example.com/user');
if (!response.ok) {
throw new Error('Network error');
}
const json = await response.json();
return json as ApiResponse<User>;
}Product object from the API.interface Product {
id: number;
title: string;
price: number;
}
async function fetchProduct(): Promise<ApiResponse<Product>> {
const response = await fetch('https://api.example.com/product');
if (!response.ok) {
throw new Error('Network error');
}
const json = await response.json();
return json as ApiResponse<Product>;
}async function fetchData<T>(url: string): Promise<ApiResponse<T>> { const response = await fetch(url); if (!response.ok) { throw new Error('Network error'); } const json = await response.json(); return json as ApiResponse<T>; }
This program fetches a user from a public API and uses a type-safe response structure. It prints the status, message, and user details if successful, or an error message if something goes wrong.
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
interface User {
id: number;
name: string;
}
async function fetchUser(): Promise<ApiResponse<User>> {
const response = await fetch('https://jsonplaceholder.typicode.com/users/1');
if (!response.ok) {
throw new Error('Failed to fetch user');
}
const userData = await response.json();
return {
data: { id: userData.id, name: userData.name },
status: response.status,
message: 'User fetched successfully'
};
}
fetchUser()
.then(result => {
console.log(`Status: ${result.status}`);
console.log(`Message: ${result.message}`);
console.log(`User ID: ${result.data.id}`);
console.log(`User Name: ${result.data.name}`);
})
.catch(error => {
console.error('Error:', error.message);
});Always check if the network response is okay before using the data.
Type assertions like as ApiResponse<T> tell TypeScript what to expect but do not check data at runtime.
For full safety, consider validating the data shape at runtime using libraries like zod or io-ts.
Type-safe API response handling helps catch errors early by defining expected data shapes.
Use TypeScript interfaces and generics to describe API responses clearly.
Always handle possible errors like network failures or unexpected data.
Practice
Solution
Step 1: Understand type safety purpose
Type-safe handling means defining what data should look like before using it.Step 2: Identify the benefit
This helps catch mistakes early, like missing or wrong data types, before running the program.Final Answer:
It helps catch errors early by defining expected data shapes. -> Option DQuick Check:
Type safety = Early error detection [OK]
- Thinking type safety improves API speed
- Believing it fixes bugs automatically
- Assuming it replaces testing
Solution
Step 1: Understand generic function syntax
Generic functions use <T> to represent a type parameter, allowing flexible typing.Step 2: Check return type for async fetch
Fetching data returns a Promise of type T, so the return type must be Promise<T>.Final Answer:
function fetchData<T>(url: string): Promise<T> { /* ... */ } -> Option BQuick Check:
Generic + Promise = function fetchData<T>(url: string): Promise<T> { /* ... */ } [OK]
- Returning T directly instead of Promise<T>
- Missing generic <T> in function definition
- Using Promise<any> loses type safety
interface User { id: number; name: string; }
async function getUser(): Promise<User> {
return { id: 1, name: "Alice" };
}
getUser().then(user => console.log(user.name));Solution
Step 1: Analyze the getUser function
It returns a Promise resolving to an object with id 1 and name "Alice".Step 2: Check the then callback
The callback logs user.name, which is "Alice".Final Answer:
"Alice" -> Option CQuick Check:
user.name = "Alice" [OK]
- Logging user instead of user.name
- Confusing id with name
- Expecting entire object printed
interface ApiResponse { success: boolean; data: string; }
async function fetchApi(): Promise<ApiResponse> {
const response = await fetch('https://api.example.com');
const json = await response.json();
return json;
}Solution
Step 1: Check how json is handled
json is returned directly without confirming it matches ApiResponse shape.Step 2: Understand type safety requirement
TypeScript needs either a type assertion or runtime validation to ensure json fits ApiResponse.Final Answer:
Missing type assertion or validation for json before returning. -> Option AQuick Check:
Validate json shape before return [OK]
- Assuming fetch json is automatically typed
- Ignoring need for runtime checks
- Misunderstanding async/await usage
Solution
Step 1: Define User interface including 'active' property
To filter by active status, the User type must include an 'active' boolean field.Step 2: Fetch data as Promise<User[]> and filter
Fetching with correct type ensures type safety; filtering users by active keeps the result accurate and typed.Final Answer:
Define interface User with 'active' boolean, fetch data as Promise<User[]>, then filter users by active before returning. -> Option AQuick Check:
Correct interface + typed fetch + filter = Define interface User with 'active' boolean, fetch data as Promise, then filter users by active before returning. [OK]
- Casting any to User[] without checks
- Filtering on missing properties in interface
- Returning unfiltered data losing requirements
Ready to prove it?
Pass the test and this pattern moves unknown
