Type-safe API calls ensure that your request and response data are correctly typed, making your code less error-prone and easier to maintain.
🧱 Why Type Safety Matters?
Without types:
fetch('/api/user')
.then(res => res.json())
.then(data => {
console.log(data.name); // 😬 Might throw if name is undefined
});With types:
interface User {
id: number;
name: string;
email: string;
}
fetch('/api/user')
.then(res => res.json())
.then((data: User) => {
console.log(data.name); // ✅ Type-safe
});📦 Using Axios with Generics (Recommended)
Axios supports generics, making it great for type-safe APIs.
✅ Example
import axios from 'axios';
interface User {
id: number;
name: string;
email: string;
}
const fetchUser = async () => {
const response = await axios.get<User>('/api/user');
return response.data;
};Here:
axios.get<User>ensures the response will match theUserinterface.You get type inference, auto-completion, and type-checking.
🧮 Typing API Parameters
You can also type request payloads:
interface LoginRequest {
username: string;
password: string;
}
interface LoginResponse {
token: string;
userId: number;
}
const login = async (credentials: LoginRequest) => {
const response = await axios.post<LoginResponse>('/api/login', credentials);
return response.data;
};🔁 Reusable Typed API Client
const apiClient = axios.create({
baseURL: '/api',
headers: {
'Content-Type': 'application/json',
},
});
interface ApiResponse<T> {
data: T;
status: number;
}
const getTyped = async <T>(url: string): Promise<ApiResponse<T>> => {
const res = await apiClient.get<T>(url);
return { data: res.data, status: res.status };
};
// Usage:
interface Product {
id: number;
name: string;
}
const getProduct = () => getTyped<Product>('/product/1');🧠 Summary
Feature | Benefit |
|---|---|
Generic response typing | Type-safe response data |
Interface-based input types | Prevents sending wrong payloads |
Reusable API wrapper | DRY and consistent request patterns |
IDE support | Autocompletion and refactoring help |