Lesson 60 of 60 – TypeScript in React Native
100%

TypeScript in React Native

React Native allows developers to build mobile applications using React concepts. TypeScript can be used with React Native to add static typing to components, props, state, functions, navigation, API responses, forms, and reusable application logic.

Note: TypeScript does not replace React Native. It adds a type system that helps detect many coding mistakes during development and makes larger mobile applications easier to maintain.

1. What is TypeScript in React Native?

TypeScript in React Native means writing React Native application code using TypeScript instead of plain JavaScript.

const message: string =
    "Hello React Native";

TypeScript can type variables, functions, components, props, state, and many other parts of an application.

2. Why Use TypeScript with React Native?

  • Provides static type checking.
  • Improves editor autocomplete.
  • Helps detect incorrect values.
  • Makes component props easier to understand.
  • Improves code maintainability.
  • Works well with larger applications.

3. React Native Components Can Be Typed

React Native components receive props and values that can be checked with TypeScript.

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

function App() {

    return (
        <View>
            <Text>
                Hello React Native
            </Text>
        </View>
    );
}

4. TypeScript Project Files

React Native TypeScript projects commonly use .ts files for TypeScript logic and .tsx files when JSX is included.

App.tsx
Student.ts
StudentScreen.tsx
api.ts

Components containing JSX are normally written using the .tsx extension.

5. Basic React Native TypeScript Component

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

function App(): React.JSX.Element {

    return (
        <View>
            <Text>
                Welcome
            </Text>
        </View>
    );
}

export default App;

6. Typing Component Props

interface UserProps {
    name: string;
    age: number;
}

function User({
    name,
    age
}: UserProps): React.JSX.Element {

    return (
        <View>
            <Text>{name}</Text>
            <Text>Age: {age}</Text>
        </View>
    );
}

7. Passing Props

<User
    name="Rahul"
    age={20}
/>

TypeScript checks that the supplied props match the UserProps interface.

8. Typing useState

const [name, setName] =
    useState<string>("");

const [count, setCount] =
    useState<number>(0);

const [active, setActive] =
    useState<boolean>(false);

TypeScript can explicitly define the type of React Native component state.

9. Typing TextInput

import {
    TextInput
} from "react-native";

const [name, setName] =
    useState<string>("");

return (
    <TextInput
        value={name}
        onChangeText={setName}
        placeholder="Enter name"
    />
);

The onChangeText callback receives the new text value as a string.

10. Typing Button Events

import {
    Button
} from "react-native";

const handlePress = (): void => {
    console.log("Button pressed");
};

return (
    <Button
        title="Save"
        onPress={handlePress}
    />
);

The function does not return a value, so it can be typed as void.

11. Typing View Components

React Native's View is used to create containers for other components.

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

function Profile(): React.JSX.Element {

    return (
        <View>
            <Text>
                Student Profile
            </Text>
        </View>
    );
}

12. Typing StyleSheet

import {
    StyleSheet
} from "react-native";

const styles = StyleSheet.create({

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

    title: {
        fontSize: 24
    }

});

React Native's StyleSheet.create() helps organize component styles.

13. Typing FlatList Data

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

const students: Student[] = [
    {
        id: 1,
        name: "Rahul"
    },
    {
        id: 2,
        name: "Amit"
    }
];

The Student[] type ensures that every item follows the student structure.

14. FlatList with TypeScript

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

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

interface Props {
    students: Student[];
}

function StudentList({
    students
}: Props): React.JSX.Element {

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

15. Typing API Response Data

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

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

The interface describes the expected structure of each API student object.

16. Fetching API Data

useEffect(() => {

    const loadStudents = async () => {

        const response =
            await fetch("/api/students");

        const data: Student[] =
            await response.json();

        setStudents(data);
    };

    loadStudents();

}, []);

17. Loading and Error State

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

const [error, setError] =
    useState<string | null>(null);

These states can be used to display loading and error messages while API data is being loaded.

18. Typing Navigation Props

React Navigation can be combined with TypeScript to define screen names and route parameters.

type RootStackParamList = {
    Home: undefined;
    Details: {
        studentId: number;
    };
};

This type describes the available routes and their parameters.

19. Typing Route Parameters

type RootStackParamList = {
    Home: undefined;
    Details: {
        studentId: number;
    };
};

type DetailsScreenProps = {
    route: {
        params: {
            studentId: number;
        };
    };
};

The studentId parameter is required to be a number.

20. Reusable Component with TypeScript

interface StudentCardProps {
    name: string;
    course: string;
}

function StudentCard({
    name,
    course
}: StudentCardProps): React.JSX.Element {

    return (
        <View>

            <Text>
                {name}
            </Text>

            <Text>
                {course}
            </Text>

        </View>
    );
}

21. Interfaces for User Data

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

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

Interfaces are useful for keeping user-related data consistent across multiple screens.

22. Typed Form in React Native

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

const [form, setForm] =
    useState<LoginForm>({
        email: "",
        password: ""
    });

A form interface makes the structure of the form state clear.

23. React Native TextInput Form

const [email, setEmail] =
    useState<string>("");

const [password, setPassword] =
    useState<string>("");

return (
    <View>

        <TextInput
            value={email}
            onChangeText={setEmail}
            placeholder="Email"
        />

        <TextInput
            value={password}
            onChangeText={setPassword}
            placeholder="Password"
            secureTextEntry={true}
        />

    </View>
);

24. AsyncStorage with TypeScript

import AsyncStorage
    from "@react-native-async-storage/async-storage";

const saveName = async (
    name: string
): Promise<void> => {

    await AsyncStorage.setItem(
        "name",
        name
    );
};

TypeScript can also type functions used for local storage operations.

25. Axios with TypeScript

import axios from "axios";

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

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

    const response =
        await axios.get<Student[]>(
            "/api/students"
        );

    return response.data;
};

The generic type tells TypeScript what data is expected from the Axios response.

26. Context API with TypeScript

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

interface AuthContextType {
    user: User | null;
    login: (user: User) => void;
    logout: () => void;
}

An interface can define the values and functions available through a Context.

27. Redux Toolkit with TypeScript

TypeScript can also describe Redux state and actions.

interface CounterState {
    value: number;
}

const initialState: CounterState = {
    value: 0
};

Typed Redux state makes application-wide data easier to manage safely.

28. TypeScript Project Structure

src/
│
├── components/
│   ├── Button.tsx
│   └── StudentCard.tsx
│
├── screens/
│   ├── HomeScreen.tsx
│   └── DetailsScreen.tsx
│
├── types/
│   └── student.ts
│
├── services/
│   └── api.ts
│
├── navigation/
│   └── AppNavigator.tsx
│
└── App.tsx

Separating components, screens, types, services, and navigation can make a growing project easier to organize.

29. Benefits of TypeScript for Mobile Applications

  • Safer component props.
  • Typed navigation parameters.
  • Typed API responses.
  • Better form handling.
  • Safer state management.
  • Improved code completion.
  • Easier refactoring.
  • Better structure for larger applications.
  • Fewer type-related mistakes during development.

30. Complete React Native TypeScript Example

import {
    useEffect,
    useState
} from "react";

import {
    View,
    Text,
    TextInput,
    Button,
    StyleSheet
} from "react-native";

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

function App(): React.JSX.Element {

    const [name, setName] =
        useState<string>("");

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

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

    const addStudent = (): void => {

        if (!name.trim()) {
            return;
        }

        const student: Student = {
            id: students.length + 1,
            name: name,
            course: "React Native"
        };

        setStudents(previousStudents => [
            ...previousStudents,
            student
        ]);

        setName("");
    };

    useEffect(() => {

        console.log(
            "Student count:",
            students.length
        );

    }, [students]);

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

            <Text style={styles.title}>
                Student Management
            </Text>

            <TextInput
                style={styles.input}
                value={name}
                onChangeText={setName}
                placeholder="Enter student name"
            />

            <Button
                title="Add Student"
                onPress={addStudent}
                disabled={loading}
            />

            {students.map(student => (

                <View
                    key={student.id}
                    style={styles.card}
                >

                    <Text>
                        ID: {student.id}
                    </Text>

                    <Text>
                        Name: {student.name}
                    </Text>

                    <Text>
                        Course: {student.course}
                    </Text>

                </View>

            ))}

        </View>
    );
}

const styles = StyleSheet.create({

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

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

    input: {
        borderWidth: 1,
        padding: 10,
        marginBottom: 15
    },

    card: {
        padding: 15,
        marginTop: 10,
        borderWidth: 1
    }

});

export default App;

This example combines TypeScript interfaces, useState, useEffect, TextInput, Button, typed functions, arrays, React Native components, and StyleSheet.

📌 Key Points

  • React Native applications can be written using TypeScript.
  • Use .tsx files for TypeScript components containing JSX.
  • Interfaces can define component props and application data.
  • useState can be explicitly typed.
  • React Native components such as TextInput and Button have their own event APIs.
  • API responses can be described using TypeScript interfaces.
  • Navigation route parameters can be typed.
  • Forms, AsyncStorage, Axios, Context API, and Redux Toolkit can all be used with TypeScript.
  • TypeScript is especially useful as React Native applications become larger.

🧠 Quick Quiz

Question: Which file extension is commonly used for a React Native TypeScript component containing JSX?