Rechu's solution works fine, but I have an alternative approach.
To maintain a global axios
instance, you can create a reusable function. This is a method I personally use in live projects.
To begin, create a folder/file named utils/http.ts
within your project. Here is the custom function that consolidates everything:
import axiosClient from "axios";
import type { AxiosRequestConfig } from "axios";
/**
* Initializes an 'axios' instance with customized settings.
*/
const instance = axiosClient.create({
headers: {
Accept: "application/json",
"Content-Type": "application/json; charset=utf-8",
},
});
/**
* Handles all responses. It's possible to include request handlers as well,
* omitted here for simplicity.
*/
instance.interceptors.response.use(
(res) => res.data,
(err) => {
if (err.response) {
return Promise.reject(err.response.data);
}
if (err.request) {
return Promise.reject(err.request);
}
return Promise.reject(err.message);
}
);
/**
* Replaces main `axios` instance with the customized one.
*
* @param cfg - Configuration object for Axios.
* @returns A promise containing the response of the HTTP request with the 'data' object already
* deconstructed.
*/
const axios = <T>(cfg: AxiosRequestConfig) => instance.request<any, T>(cfg);
export default axios;
Finally, implement it as shown in the code snippet below:
const login = () => {
const creds = { username: "user", password: "pass" };
axios<User>({ method: "POST", url: "/api/v1/auth/login", data: creds })
.then((user) => { /* process user data */ })
.catch((err) => { /* handle errors */ );
};
This setup will be properly typed and immediately usable. You can replace any
with unknown
within the axios
function as needed.