Lesson 72 of 60 – Interfaces for User Data
100%

Interfaces for User Data

React Native applications frequently work with user information such as name, email, mobile number, profile image, age, address, and user ID. TypeScript interfaces allow us to clearly define the structure of this data.

Once a user interface is created, it can be reused with state, API responses, FlatList, navigation, forms, and reusable components.

Note: In this lesson, an interface means a TypeScript interface used to describe the structure of user data. It is different from a React Native screen or UI interface.

1. What is User Data?

User data is information stored about a person using an application.

For example:

{
    id: 101,
    name: "Rahul",
    email: "rahul@example.com",
    age: 21
}

2. Why Create an Interface for User Data?

An interface gives user data a clear and reusable structure.

  • Defines property names.
  • Defines property types.
  • Improves code completion.
  • Helps detect incorrect values.
  • Can be reused throughout the application.

3. Creating a User Interface

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

This interface says that every User object must contain id, name, and email.

4. Creating a User Object

const user: User = {
    id: 101,
    name: "Rahul",
    email: "rahul@example.com"
};

The User interface tells TypeScript what properties the object should contain.

5. Adding More User Properties

interface User {
    id: number;
    name: string;
    email: string;
    phone: string;
    age: number;
}

An interface can contain as many properties as the application needs.

6. Boolean User Properties

Boolean properties can represent states such as whether a user is active.

interface User {
    id: number;
    name: string;
    active: boolean;
}
const user: User = {
    id: 101,
    name: "Rahul",
    active: true
};

7. Optional User Properties

Some user information may not always be available. Use ? for optional properties.

interface User {
    id: number;
    name: string;
    email: string;
    phone?: string;
}

The phone number does not have to be included in every User object.

8. Readonly User ID

A user ID can be marked as readonly when it should not be changed through the typed object.

interface User {
    readonly id: number;
    name: string;
    email: string;
}

This helps protect the ID from accidental reassignment in TypeScript code.

9. User Address Interface

User data can contain nested objects.

interface Address {
    city: string;
    state: string;
    pincode: string;
}

interface User {
    id: number;
    name: string;
    address: Address;
}

10. Creating a User with Address

const user: User = {
    id: 101,
    name: "Rahul",
    address: {
        city: "Patna",
        state: "Bihar",
        pincode: "800001"
    }
};

The nested address object must follow the Address interface.

11. User with Profile Information

interface Profile {
    bio: string;
    image: string;
}

interface User {
    id: number;
    name: string;
    profile: Profile;
}

Separate interfaces can make complex user data easier to understand.

12. User Data in useState

const [user, setUser] =
    useState<User | null>(null);

The state can contain a User object or null when user data has not been loaded yet.

13. Setting User State

setUser({
    id: 101,
    name: "Rahul",
    email: "rahul@example.com"
});

TypeScript checks that the object matches the User interface.

14. Displaying User Data

{user && (
    <View>

        <Text>
            {user.name}
        </Text>

        <Text>
            {user.email}
        </Text>

    </View>
)}

The condition makes sure that user data exists before accessing it.

15. User Data from an API

const response =
    await fetch(
        "https://example.com/api/user"
    );

const data: User =
    await response.json();

setUser(data);

The response can be represented using the User interface in application code.

16. User Array

If an API returns multiple users, use an array of the User interface.

const users: User[] = [
    {
        id: 1,
        name: "Rahul",
        email: "rahul@example.com"
    },
    {
        id: 2,
        name: "Priya",
        email: "priya@example.com"
    }
];

17. User Data with FlatList

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

        <View>

            <Text>
                {item.name}
            </Text>

            <Text>
                {item.email}
            </Text>

        </View>

    )}
/>

18. User Interface with Role

A union type can restrict a user's role to specific values.

interface User {
    id: number;
    name: string;
    role: "admin" | "student" | "teacher";
}

TypeScript will only accept the specified role values.

19. User Interface with Status

interface User {
    id: number;
    name: string;
    status: "active" | "inactive";
}

This is useful when an application needs a fixed set of user statuses.

20. User Interface for Forms

A User interface can also be used as the basis for form data.

interface UserForm {
    name: string;
    email: string;
    phone: string;
}
const [form, setForm] =
    useState<UserForm>({
        name: "",
        email: "",
        phone: ""
    });

21. Updating User Form Data

setForm(prev => ({
    ...prev,
    name: "Rahul"
}));

The spread operator keeps the other properties while updating one field.

22. User Interface as Component Props

interface UserCardProps {
    user: User;
}

function UserCard(
    { user }: UserCardProps
): React.JSX.Element {

    return (
        <View>

            <Text>
                {user.name}
            </Text>

            <Text>
                {user.email}
            </Text>

        </View>
    );
}

23. User Interface with Callback

interface UserCardProps {
    user: User;
    onSelect: (user: User) => void;
}

The callback receives a complete User object.

onPress={() =>
    onSelect(user)
}

24. Common Mistakes

  • Using any instead of a User interface.
  • Using incorrect property names.
  • Assigning a number to a string property.
  • Forgetting optional properties.
  • Accessing a nullable user without checking it.
  • Using inconsistent user structures in different screens.
  • Not reusing the same interface across related components.

25. Separating User Types into a File

In larger applications, shared interfaces can be placed in a separate types file.

// types/User.ts

export interface User {
    id: number;
    name: string;
    email: string;
}

The interface can then be imported wherever it is required.

26. Importing the User Interface

import {
    User
} from "./types/User";

Shared types help keep the structure of user data consistent throughout the application.

27. User Interface in a Navigation Screen

User objects can also be passed between React Navigation screens when the route parameter type is defined appropriately.

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

type RootStackParamList = {
    Home: undefined;
    Profile: {
        user: User;
    };
};

The Profile screen can then receive a correctly typed User object.

28. Complete User Data Example

import React, {
    useState
} from "react";

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

interface User {
    readonly id: number;
    name: string;
    email: string;
    phone?: string;
    role: "admin" | "student" | "teacher";
}

const users: User[] = [
    {
        id: 1,
        name: "Rahul",
        email: "rahul@example.com",
        phone: "9876543210",
        role: "student"
    },
    {
        id: 2,
        name: "Priya",
        email: "priya@example.com",
        role: "teacher"
    }
];

export default function App(): React.JSX.Element {

    const [selectedUser, setSelectedUser] =
        useState<User | null>(null);

    const handleSelect =
        (user: User): void => {

        setSelectedUser(user);

    };

    return (
        <View style={styles.container}>

            <Text style={styles.title}>
                User List
            </Text>

            <FlatList<User>
                data={users}

                keyExtractor={(item) =>
                    item.id.toString()
                }

                renderItem={({ item }) => (

                    <Pressable
                        style={styles.card}
                        onPress={() =>
                            handleSelect(item)
                        }
                    >

                        <Text style={styles.name}>
                            {item.name}
                        </Text>

                        <Text>
                            {item.email}
                        </Text>

                        <Text>
                            Role: {item.role}
                        </Text>

                        <Text>
                            Phone: {
                                item.phone ??
                                "Not available"
                            }
                        </Text>

                    </Pressable>

                )}
            />

            {selectedUser && (

                <Text style={styles.selected}>
                    Selected: {selectedUser.name}
                </Text>

            )}

        </View>
    );
}

const styles = StyleSheet.create({

    container: {
        flex: 1,
        padding: 20
    },

    title: {
        fontSize: 24,
        fontWeight: "bold",
        marginBottom: 15
    },

    card: {
        padding: 15,
        marginBottom: 10,
        borderWidth: 1,
        borderRadius: 8
    },

    name: {
        fontSize: 18,
        fontWeight: "bold"
    },

    selected: {
        marginTop: 15,
        fontSize: 18
    }

});

29. Best Practices for User Interfaces

  • Use a clear name such as User for the main user model.
  • Use descriptive property names.
  • Use optional properties only when appropriate.
  • Use union types for fixed values such as roles and statuses.
  • Reuse the same User interface across screens.
  • Keep shared interfaces in a dedicated types folder in larger projects.
  • Use typed user data with API, FlatList, forms, and navigation.

30. Summary

User data appears in almost every real-world application. TypeScript interfaces provide a clear structure for this data and allow the same structure to be reused across components, forms, API responses, FlatLists, and navigation.

You should now understand how to create User interfaces, use optional and readonly properties, create nested user data, store users in state, display users in FlatList, pass users through props, use callback functions, and organize shared user types.

📌 Key Points

  • Create a User interface to describe user information.
  • Use appropriate types for every user property.
  • Use ? for optional user properties.
  • Use readonly for values that should not be reassigned.
  • Use union types for roles and statuses.
  • Use User[] for multiple users.
  • Use User | null for user state that may initially be empty.
  • Reuse User interfaces across API, forms, FlatList, components, and navigation.

🧠 Quick Quiz

Question: Which TypeScript syntax correctly defines an array of User objects?