Lesson 121 of 158 – TypeScript with Axios
77%

TypeScript with Axios

Axios is commonly used in React Native applications to communicate with REST APIs. When Axios is combined with TypeScript, we can type request data, response data, errors, and reusable API functions.

Note: In this lesson, we will learn how to use TypeScript with Axios while communicating with a PHP/MySQL REST API.

1. What is Axios?

Axios is a JavaScript library used to make HTTP requests to APIs.

import axios from "axios";

It can be used with GET, POST, PUT, PATCH, and DELETE requests.

2. Why Use TypeScript with Axios?

  • Type API responses.
  • Type API request bodies.
  • Type query parameters.
  • Type API errors.
  • Improve code completion.
  • Reduce data-type mistakes.

3. Installing Axios

Install Axios in the React Native project:

npm install axios

After installation, Axios can be imported into TypeScript files.

4. Importing Axios

import axios from "axios";

We can now use Axios to communicate with the PHP REST API.

5. Creating an Axios Instance

const api = axios.create({
    baseURL: "https://example.com/api"
});

export default api;

A reusable Axios instance keeps API configuration in one place.

6. Creating a Student Interface

interface Student {
    id: number;
    name: string;
    email: string;
    mobile: string;
}

This interface describes one student returned by the API.

7. Creating an API Response Interface

interface StudentResponse {
    success: boolean;
    message: string;
    data: Student[];
}

This interface describes a response containing multiple students.

8. Typed Axios GET Request

const response =
    await api.get<StudentResponse>(
        "/students"
    );

The generic type tells TypeScript what structure to expect from the response.

9. Reading Typed GET Data

const response =
    await api.get<StudentResponse>(
        "/students"
    );

const students = response.data.data;

console.log(students);

TypeScript understands that students is a Student[].

10. Typed POST Request

interface CreateStudentRequest {
    name: string;
    email: string;
    mobile: string;
}

const studentData: CreateStudentRequest = {
    name: "Rahul",
    email: "rahul@example.com",
    mobile: "9876543210"
};

await api.post(
    "/students",
    studentData
);

11. Typed POST Response

interface CreateStudentResponse {
    success: boolean;
    message: string;
    data: Student;
}

const response =
    await api.post<CreateStudentResponse>(
        "/students",
        studentData
    );

console.log(response.data.data);

12. Typed PUT Request

interface UpdateStudentRequest {
    name: string;
    email: string;
    mobile: string;
}

const data: UpdateStudentRequest = {
    name: "Rahul Kumar",
    email: "rahul@example.com",
    mobile: "9876543210"
};

const response =
    await api.put(
        "/students/10",
        data
    );

13. Typed DELETE Request

interface DeleteResponse {
    success: boolean;
    message: string;
}

const response =
    await api.delete<DeleteResponse>(
        "/students/10"
    );

console.log(response.data.message);

14. Typed Query Parameters

interface StudentQuery {
    search?: string;
    page?: number;
    limit?: number;
}

const params: StudentQuery = {
    search: "Rahul",
    page: 1,
    limit: 10
};

const response =
    await api.get<StudentResponse>(
        "/students",
        {
            params
        }
    );

15. Typed Sorting Parameters

interface SortParams {
    sort: string;
    order: "asc" | "desc";
}

const params: SortParams = {
    sort: "name",
    order: "asc"
};

const response =
    await api.get<StudentResponse>(
        "/students",
        {
            params
        }
    );

16. Typed Pagination Response

interface PaginationMeta {
    page: number;
    limit: number;
    total: number;
    totalPages: number;
}

interface StudentListResponse {
    success: boolean;
    message: string;
    data: Student[];
    meta: PaginationMeta;
}

Pagination metadata can also be strongly typed.

17. Axios and React Native State

const [students, setStudents] =
    useState<Student[]>([]);

const loadStudents = async () => {

    const response =
        await api.get<StudentResponse>(
            "/students"
        );

    setStudents(response.data.data);
};

18. Typed Loading State

const [loading, setLoading] =
    useState<boolean>(false);
const loadStudents = async () => {

    try {

        setLoading(true);

        const response =
            await api.get<StudentResponse>(
                "/students"
            );

        setStudents(response.data.data);

    } finally {

        setLoading(false);

    }
};

19. Typed API Errors

interface ApiError {
    success: boolean;
    message: string;
    errors?: {
        [field: string]: string[];
    };
}

This interface can describe validation and other structured API errors.

20. Handling Typed Axios Errors

try {

    await api.get("/students");

} catch (error) {

    if (axios.isAxiosError<ApiError>(error)) {

        console.log(
            error.response?.data.message
        );

    }
}

21. Typed Authentication Request

interface LoginRequest {
    email: string;
    password: string;
}

interface LoginResponse {
    success: boolean;
    message: string;
    token: string;
    user: {
        id: number;
        name: string;
        email: string;
    };
}

22. Typed Axios Login

const loginData: LoginRequest = {
    email: "user@example.com",
    password: "123456"
};

const response =
    await api.post<LoginResponse>(
        "/login",
        loginData
    );

const token = response.data.token;

23. Axios Headers with TypeScript

const response =
    await api.get<StudentResponse>(
        "/students",
        {
            headers: {
                Accept: "application/json",
                Authorization: `Bearer ${token}`
            }
        }
    );

Headers can be added to typed Axios requests just like normal Axios requests.

24. Typed API Function

API operations can be placed inside reusable functions.

const getStudents =
    async (): Promise<Student[]> => {

    const response =
        await api.get<StudentResponse>(
            "/students"
        );

    return response.data.data;
};

The function promises to return a Student[].

25. Typed Create Function

const createStudent =
    async (
        data: CreateStudentRequest
    ): Promise<Student> => {

    const response =
        await api.post<CreateStudentResponse>(
            "/students",
            data
        );

    return response.data.data;
};

26. Avoiding any with Axios

Avoid unnecessarily using any for API responses.

// Avoid

const response: any =
    await api.get("/students");

Prefer:

const response =
    await api.get<StudentResponse>(
        "/students"
    );

This allows TypeScript to understand the response structure.

27. Common TypeScript + Axios Mistakes

  • Using the wrong response interface.
  • Using any for every API response.
  • Forgetting optional API properties.
  • Using incorrect request property names.
  • Not checking for Axios errors.
  • Ignoring HTTP status codes.
  • Not handling network errors.
  • Putting API logic inside every screen instead of reusable functions.

28. Complete Axios API Service

import axios from "axios";

export interface Student {
    id: number;
    name: string;
    email: string;
    mobile: string;
}

export interface StudentResponse {
    success: boolean;
    message: string;
    data: Student[];
}

const api = axios.create({
    baseURL: "https://example.com/api",
    headers: {
        Accept: "application/json"
    }
});

export const getStudents =
    async (): Promise<Student[]> => {

    const response =
        await api.get<StudentResponse>(
            "/students"
        );

    return response.data.data;
};

export default api;

29. Complete React Native Axios Example

import React, {
    useEffect,
    useState
} from "react";

import {
    View,
    Text,
    FlatList
} from "react-native";

import api from "./api";

interface Student {
    id: number;
    name: string;
    email: string;
    mobile: string;
}

interface StudentResponse {
    success: boolean;
    message: string;
    data: Student[];
}

const StudentList = () => {

    const [students, setStudents] =
        useState<Student[]>([]);

    const [loading, setLoading] =
        useState<boolean>(false);

    const loadStudents = async () => {

        try {

            setLoading(true);

            const response =
                await api.get<StudentResponse>(
                    "/students"
                );

            setStudents(response.data.data);

        } catch (error) {

            console.log(error);

        } finally {

            setLoading(false);

        }
    };

    useEffect(() => {
        loadStudents();
    }, []);

    return (
        <View>

            {loading && (
                <Text>Loading...</Text>
            )}

            <FlatList
                data={students}
                keyExtractor={item =>
                    item.id.toString()
                }
                renderItem={({ item }) => (

                    <View>
                        <Text>{item.name}</Text>
                        <Text>{item.email}</Text>
                        <Text>{item.mobile}</Text>
                    </View>

                )}
                ListEmptyComponent={
                    <Text>No students found</Text>
                }
            />

        </View>
    );
};

export default StudentList;

30. Complete TypeScript + Axios Flow

React Native
      ↓
TypeScript Request Interface
      ↓
Axios
      ↓
PHP REST API
      ↓
MySQL
      ↓
JSON Response
      ↓
TypeScript Response Interface
      ↓
React Native State
      ↓
FlatList / UI

TypeScript provides structure for the request and response, while Axios handles communication with the PHP REST API.

For example, a student list screen can use a typed Axios response, store the returned Student[] in state, and display the records using FlatList.

📌 Key Points

  • Axios can be used with TypeScript in React Native.
  • Interfaces can describe API request and response structures.
  • Axios generics can type response data.
  • Request bodies can be strongly typed.
  • Query parameters can also be typed.
  • Axios errors can be checked with axios.isAxiosError().
  • Reusable typed API functions make application code cleaner.
  • Typed API functions can return specific types such as Student[].
  • Avoid using any when the API structure is known.
  • TypeScript and Axios provide a safer way to connect React Native with REST APIs.

🧠 Quick Quiz

Question: Which Axios syntax is used to specify the TypeScript type of the response?