interface ApiError {
message: string;
status: number;
}
async function fetchJson<T>(url: string, options?: RequestInit): Promise<T> {
const response = await fetch(url, {
headers: { 'Content-Type': 'application/json' },
...options,
});
if (!response.ok) {
const error: ApiError = {
message: response.statusText,
status: response.status,
};
throw error;
}
return response.json() as Promise<T>;
}
// HTTP methods
const api = {
get: <T>(url: string) => fetchJson<T>(url),
post: <T, B>(url: string, body: B) =>
fetchJson<T>(url, {
method: 'POST',
body: JSON.stringify(body),
}),
put: <T, B>(url: string, body: B) =>
fetchJson<T>(url, {
method: 'PUT',
body: JSON.stringify(body),
}),
delete: <T>(url: string) => fetchJson<T>(url, { method: 'DELETE' }),
};Usage
interface User {
id: number;
name: string;
}
const user = await api.get<User>('/api/users/1');
const newUser = await api.post<User, Omit<User, 'id'>>('/api/users', {
name: 'John',
});



