Lesson 116 of 158 – TypeScript Interfaces for API Data
73%

TypeScript Interfaces for API Data

When a React Native application receives JSON data from a REST API, TypeScript interfaces can describe the structure of that data. This helps us write safer and easier-to-understand API code.

Note: In this lesson, we will create TypeScript interfaces for data returned by a PHP/MySQL REST API and use them with React Native and Axios.

1. What is a TypeScript Interface?

An interface defines the expected structure of an object.

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

This means a Student object should contain an ID, name, and email.

2. Why Use Interfaces with APIs?

API interfaces provide several benefits:

  • Describe the JSON response structure.
  • Provide better editor suggestions.
  • Catch type mistakes during development.
  • Make API code easier to understand.
  • Improve React Native application maintainability.

3. Basic Student Interface

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

This interface can represent a student returned by a REST API.

4. Matching JSON with an Interface

Suppose the PHP API returns:

{
    "id": 101,
    "name": "Rahul Kumar",
    "email": "rahul@example.com",
    "mobile": "9876543210"
}

The matching TypeScript interface is:

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

5. String Properties

API fields containing text can be defined as string.

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

TypeScript will expect these properties to contain string values.

6. Number Properties

Numeric API fields can use the number type.

interface Student {
    id: number;
    age: number;
    fee: number;
}

Use the type that matches the data returned by your API.

7. Boolean Properties

Boolean API values can be represented using boolean.

interface Student {
    id: number;
    name: string;
    active: boolean;
}

The API may return true or false.

8. Optional API Properties

Sometimes an API property may not always be present. Use ? to make an interface property optional.

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

Here, email may or may not be included.

9. Nullable API Properties

Some APIs return null for fields that do not have a value.

interface Student {
    id: number;
    name: string;
    photo: string | null;
}

The photo can either be a string or null.

10. Array of Students

An API often returns multiple records as an array.

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

const students: Student[] = [];

Student[] means an array containing Student objects.

11. API Response Interface

Many APIs return an object containing a success message and data.

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

This interface describes the complete response structure.

12. PHP API JSON Response

A PHP REST API might return:

{
    "success": true,
    "message": "Students fetched successfully",
    "data": [
        {
            "id": 1,
            "name": "Amit",
            "email": "amit@example.com"
        },
        {
            "id": 2,
            "name": "Priya",
            "email": "priya@example.com"
        }
    ]
}

13. Creating Interfaces for Nested Data

API responses can contain nested objects.

interface Course {
    id: number;
    name: string;
}

interface Student {
    id: number;
    name: string;
    course: Course;
}

The course property contains another object.

14. Nested API JSON Example

{
    "id": 1,
    "name": "Rahul",
    "course": {
        "id": 10,
        "name": "React Native"
    }
}

The nested course object can be represented by the Course interface.

15. Typing Axios Response Data

Axios can be given a TypeScript response type.

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

console.log(response.data);

TypeScript now knows the expected structure of the API response.

16. Accessing Typed Data

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

const students = response.data.data;

students.forEach(student => {
    console.log(student.name);
});

TypeScript understands that each item is a Student.

17. Using Interfaces with useState

React Native state can also use the Student interface.

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

This tells TypeScript that the state contains an array of students.

18. Using Interfaces with FlatList

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

Because the data is typed as Student[], the item object is understood as a Student.

19. API Interface with Pagination

A paginated API can include metadata along with the records.

interface StudentResponse {
    success: boolean;
    data: Student[];
    meta: {
        page: number;
        limit: number;
        total: number;
        totalPages: number;
    };
}

20. API Error Interface

API errors can also be represented using interfaces.

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

This helps the application handle structured validation errors.

21. Login Response Interface

A login API commonly returns a token and user information.

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

22. Typing a Login API Request

Interfaces can also describe data sent to the API.

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

This interface describes the JSON body expected by the login endpoint.

23. Using the Login Interface with Axios

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

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

console.log(response.data.token);

24. Interface for Student Creation

We can create a separate interface for data sent while creating a student.

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

The interface can be used with an Axios POST request.

25. Avoiding any with API Data

Using any removes much of TypeScript's type checking.

// Avoid when possible

const data: any = response.data;

Prefer a specific interface:

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

This gives better type safety.

26. Interfaces and PHP REST API

The PHP backend produces JSON, while TypeScript interfaces describe the expected JSON structure on the React Native side.

PHP + MySQL
     ↓
JSON REST API
     ↓
Axios
     ↓
TypeScript Interface
     ↓
React Native UI

Both sides should agree on the API response structure.

27. Common Interface Mistakes

  • Using the wrong property name.
  • Using string when the API returns a number.
  • Forgetting optional properties.
  • Forgetting that an API field can be null.
  • Defining an array as a single object.
  • Not matching nested API structures.

The interface should represent the actual API contract.

28. Complete Student API Interface

interface Student {
    id: number;
    name: string;
    email: string;
    mobile: string;
    courseId: number;
    courseName?: string;
    photo: string | null;
}

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

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

29. Complete Axios Example

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

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

const loadStudents = async () => {

    try {

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

        console.log(response.data.data);

    } catch (error) {

        console.log("Unable to load students");

    }
};

Axios now knows that the expected response follows the StudentResponse structure.

30. Complete React Native 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[]>([]);

    useEffect(() => {

        const loadStudents = async () => {

            try {

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

                setStudents(response.data.data);

            } catch (error) {

                console.log(error);

            }

        };

        loadStudents();

    }, []);

    return (
        <View>

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

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

                )}
            />

        </View>
    );
};

export default StudentList;

Here, the PHP REST API returns JSON, Axios receives the response, and TypeScript uses interfaces to describe the returned data.

📌 Key Points

  • TypeScript interfaces describe the structure of API data.
  • Interfaces improve type safety in React Native applications.
  • Use string, number, and boolean according to the API data.
  • Use ? for optional properties.
  • Use null in a union when an API field can return null.
  • Use Student[] for an array of Student objects.
  • Nested API objects can have their own interfaces.
  • Axios supports typed responses using generics.
  • Request bodies can also be described with interfaces.
  • Interfaces should match the actual PHP REST API response structure.

🧠 Quick Quiz

Question: Which TypeScript syntax represents an array of Student objects?