Using React Native with TypeScript: A Guide to Scalable App Development

React Native With Typescript

React Native is one of the top platforms when it comes to cross-platform app development. You can use it to build the best apps for both iOS and Android with just one codebase. But is there a way to ensure more bug-free results? Well the answer is, yes.

You can combine React Native with TypeScript to create scalable, maintainable applications with fewer bugs. It adds static typing to catch errors early and improve code quality.

In this blog, I’ll explain how the React Native experts implement this combination to boost productivity and reduce runtime errors.

How to Set Up React Native with TypeScript?

Developing mobile apps with React Native and TypeScript improves code reliability. And it can enhance developer experience, and reduce runtime errors. Setting it up is straightforward—whether you’re starting a new project or migrating an existing one.

Create a New Project

TypeScript is included by default in React Native (v0.71 and above). You can simply run:

npx react-native init NotesApp

This will create a fresh React Native project with TypeScript already set up. You’ll see .ts and .tsx files instead of the usual .js files.

Recommended Folder Structure

Organizing your files properly from the start helps keep your app scalable:

NotesApp/
├── src/
│   ├── components/        # Reusable UI components
│   ├── screens/           # App screens
│   ├── types/             # TypeScript interfaces/types
│   └── services/          # API calls or logic files
├── App.tsx                # Root of your app
├── tsconfig.json          # TypeScript config

What’s Already Set Up?

After creating your project, these are already included:

  • App.tsx: the main app component
  • tsconfig.json: TypeScript configuration file
  • Type definitions: like @types/react and @types/react-native

No need to install any templates or extra setup. You’re ready to start building with TypeScript right away.

How to Use React Native with TypeScript?

With TypeScript, you can tell your app what kind of data it should expect. This helps catch errors early and makes your code easier to read and maintain.

Here’s how you can add TypeScript in everyday React Native code.

Component Props

Use an interface or type to describe the props your component needs:

import React from 'react';
import { Text, TouchableOpacity } from 'react-native';
interface ButtonProps {
  title: string;
  onPress: () => void;
}
const MyButton: React.FC<ButtonProps> = ({ title, onPress }) => (
  <TouchableOpacity onPress={onPress}>
    <Text>{title}</Text>
  </TouchableOpacity>
);

This makes it clear that title must be a string and onPress must be a function.

useState

You can specify the type of data you’re storing in state:

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

This makes sure you don’t accidentally assign a non-number value to count.

FlatList and Arrays

Let TypeScript know what kind of items are in your list:

interface Note {
  id: string;
  title: string;
}
const notes: Note[] = [
  { id: '1', title: 'Shopping list' },
  { id: '2', title: 'Workout plan' },
];
<FlatList
  data={notes}
  keyExtractor={(item) => item.id}
  renderItem={({ item }) => <Text>{item.title}</Text>}
/>

Functions

Even simple functions benefit from clear typing:

const addNumbers = (a: number, b: number): number => {
  return a + b;
};

Pro Tip: Use React.FC<Props>

React.FC (or React.FunctionComponent) helps with typing props and children automatically. But it’s optional–feel free to just type props directly too.

Using TypeScript like this helps your IDE give you better autocomplete, and it reduces runtime bugs by catching mistakes while you write code.

Want the best cross-platform React Native mobile app?

Using TypeScript with Common React Native Libraries

React Native apps often rely on libraries for navigation, state management, and API calls. The good news? TypeScript works great with them—and can actually make them safer and easier to use.

Here’s how you can add TypeScript to the most common React Native libraries:

React Navigation

When using React Navigation, you can define your screens and their expected parameters using a type map:

// types/navigation.ts
export type RootStackParamList = {
  Home: undefined;
  Details: { itemId: number; name: string };
};

Then, use it inside your screen components like this:

import { RouteProp, useRoute } from '@react-navigation/native';
import { RootStackParamList } from '../types/navigation';
type DetailsRouteProp = RouteProp<RootStackParamList, 'Details'>;
const DetailsScreen = () => {
  const route = useRoute<DetailsRouteProp>();
  return <Text>{route.params.name}</Text>;
};

This makes sure you never miss required route parameters again.

Redux Toolkit

When working with Redux, you can type your state, actions, and dispatch to avoid accidental mistakes.

// types/state.ts
export interface AppState {
  user: string;
  isLoggedIn: boolean;
}

Inside a selector or component:

import { useSelector } from 'react-redux';
import { AppState } from '../types/state';
const username = useSelector((state: AppState) => state.user);

Add typing to your actions and reducers for full type safety.

Axios (API Calls)

Typing API responses with Axios is a great way to avoid bugs when dealing with external data.

// types/User.ts
export interface User {
  id: number;
  name: string;
  email: string;
}

Use it in your API function:

import axios from 'axios';
import { User } from '../types/User';
const fetchUser = async (): Promise<User> => {
  const response = await axios.get<User>('https://api.example.com/user');
  return response.data;
};

Now, the user.name will autocomplete and TypeScript will warn you if the API response changes unexpectedly.

Other Helpful Libraries

LibraryUse CaseSupports TypeScript?
React QueryAPI state managementYes
React Hook FormForms and validationYes
Zod or YupSchema validationYes

All of them offer excellent TypeScript support out-of-the-box, making your app safer and more developer-friendly.

How to Write Clean, Typed, and Reusable Code with TypeScript?

Writing scalable and maintainable code in React Native is all about keeping things modular, typed, and cleanly organized. TypeScript helps you build reusable components with clarity, while good project structure and tooling keep everything in check.

Let’s look at how to do it right:

Typed & Reusable Components

When building UI components, define their props using interface or type. This makes your components reusable and ensures they’re used correctly every time.

// components/NoteCard.tsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
type NoteCardProps = {
  title: string;
  content: string;
};
const NoteCard: React.FC<NoteCardProps> = ({ title, content }) => (
  <View style={styles.card}>
    <Text style={styles.title}>{title}</Text>
    <Text>{content}</Text>
  </View>
);
const styles = StyleSheet.create({
  card: { padding: 16, backgroundColor: '#f2f2f2', borderRadius: 8, marginVertical: 8 },
  title: { fontWeight: 'bold', marginBottom: 4 },
});
export default NoteCard;

Clear props help prevent misuse and make development faster with autocomplete.

Organizing and Managing Types

Create a dedicated folder to store your custom types and interfaces. This keeps your project tidy and makes types easy to reuse across components.

src/
├── components/
├── screens/
├── types/
│   ├── Note.ts
│   └── Navigation.ts

Example: types/Note.ts

export interface Note {
  id: string;
  title: string;
  content: string;
}

Now, you can import and use the Note type wherever it’s needed:

import { Note } from '../types/Note';
const notes: Note[] = [...];

Linting, Formatting & Tooling

To keep your codebase clean and consistent, set up the following tools:

Install ESLint & Prettier

npm install --save-dev eslint prettier eslint-config-prettier eslint-plugin-react eslint-plugin-react-hooks @typescript-eslint/eslint-plugin @typescript-eslint/parser

Basic .eslintrc.js Example:

module.exports = {
  parser: '@typescript-eslint/parser',
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:@typescript-eslint/recommended',
    'prettier',
  ],
  plugins: ['react', '@typescript-eslint'],
  rules: {
    semi: ['error', 'always'],
    quotes: ['error', 'single'],
  },
};
Prettier Config (.prettierrc)
{
  "singleQuote": true,
  "semi": true,
  "tabWidth": 2
}

Recommended Tools in VS Code

  • ESLint (extension)
  • Prettier (extension)
  • TypeScript Hero or Type Import Sorter
  • Auto Import

Pro Tip: Enable Auto-fix on Save

In VS Code, go to:

Settings → Search: “Format on Save” → Enable

Settings → Search: “ESLint: Auto Fix On Save” → Enable

Combining clear typing, modular organization, and good tooling can be beneficial. You’ll build React Native apps that are not only bug-free but also a pleasure to maintain and scale.

You can also consult with our React Native development company to ensure the best results.

How to Build a NotesApp in React Native with TypeScript?

This guide walks you through creating a simple Notes App using React Native and TypeScript, with modular structure, typed components, and navigation.

Project Setup

Follow the below step by step process to create the application:

Step 1: Initialize the Project

npx @react-native-community/cli init NotesApp

This creates a React Native project with TypeScript support by default (React Native v0.71+).

Recommended Folder Structure

Inside your project root, create a src folder:

src/
├── components/
│   └── NoteCard.tsx
├── screens/
│   └── HomeScreen.tsx
├── navigation/
│   └── AppNavigator.tsx
├── types/
│   └── Note.ts
└── App.tsx

Step 2: Update index file

Update the index.js file to load App.tsx from src.

import { AppRegistry } from 'react-native';
import App from './src/App';
import { name as appName } from './app.json';
AppRegistry.registerComponent(appName, () => App);

Step 3: Create note model

// src/types/Note.ts
export interface Note {
  id: string;
  title: string;
  content: string;
}

Step 4: Create note card component

// src/components/NoteCard.tsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { Note } from '../types/Note';
interface Props {
  note: Note;
}
const NoteCard: React.FC<Props> = ({ note }) => (
  <View style={styles.card}>
    <Text style={styles.title}>{note.title}</Text>
    <Text>{note.content}</Text>
  </View>
);
const styles = StyleSheet.create({
  card: {
    backgroundColor: '#fff',
    padding: 16,
    borderRadius: 10,
    marginBottom: 12,
    elevation: 2,
  },
  title: {
    fontWeight: 'bold',
    marginBottom: 4,
  },
});
export default NoteCard;

Step 5: Update home screen to display notes

// src/screens/HomeScreen.tsx
import React, { useState } from 'react';
import { View, FlatList, SafeAreaView, StyleSheet } from 'react-native';
import NoteCard from '../components/NoteCard';
import { Note } from '../types/Note';
const HomeScreen: React.FC = () => {
  const [notes, setNotes] = useState<Note[]>([
    { id: '1', title: 'React Native', content: 'Build apps using JS' },
    { id: '2', title: 'TypeScript', content: 'Add type safety to JavaScript' },
  ]);
  return (
    <SafeAreaView style={styles.container}>
      <FlatList
        data={notes}
        keyExtractor={(item) => item.id}
        renderItem={({ item }) => <NoteCard note={item} />}
      />
    </SafeAreaView>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
    backgroundColor: '#f5f5f5',
  },
});
export default HomeScreen;

Step 6: Install navigation dependencies

npm install @react-navigation/native
npm install @react-navigation/native-stack
npm install react-native-screens react-native-safe-area-context react-native-gesture-handler react-native-reanimated
npx pod-install ios  # (if you're on macOS)

Step 7: Create app navigator

// src/navigation/AppNavigator.tsx
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from '../screens/HomeScreen';
const Stack = createNativeStackNavigator();
const AppNavigator = () => (
  <NavigationContainer>
    <Stack.Navigator>
      <Stack.Screen name="Home" component={HomeScreen} />
    </Stack.Navigator>
  </NavigationContainer>
);
export default AppNavigator;

Step 8: Update the app entry point

Replace Default App.tsx with:

// src/App.tsx
import React from 'react';
import AppNavigator from './navigation/AppNavigator';
const App = () => {
  return <AppNavigator />;
};
export default App;

Run the App

Step 1: Start Metro Bundler

npx react-native start

Step2: Launch on Android

npx react-native run-android

Step 3: Launch on iOS (Mac only)

npx react-native run-ios

Our experts can ensure your Notes App is fully functional and leverages both React Native and TypeScript to the full extent.

Want professional assistance with your React Native project?

FAQs for using React Native with TypeScript

What are some good libraries for handling form input and validation in a React Native + TypeScript app?

For forms, react-hook-form works very well with React Native and offers TypeScript support. It’s lightweight and efficient for managing form state. For validation, yup pairs seamlessly with it, and both libraries provide excellent TypeScript typings, which help catch errors early and provide a better developer experience.

Can I use TypeScript with Redux or Zustand for state management?

TypeScript works well with both Redux and Zustand. When using Redux, you’ll benefit from strict typing in actions, reducers, and state, which improves maintainability. Zustand is also TypeScript-friendly, offering lightweight state management with full type safety and minimal boilerplate, making it ideal for small to mid-sized apps.

How do I handle navigation types safely in TypeScript?

To type your navigation in React Navigation, use the @react-navigation/native-stack or @react-navigation/core typings. You define a RootStackParamList with all screen names and their expected route parameters, then pass this into the createNativeStackNavigator<RootStackParamList>() function. This adds full type-safety to navigation props across your app.

Let’s Conclude

Building apps with React Native and TypeScript brings together the best of two outstanding platforms. The cross-platform power of React Native and the reliability of TypeScript’s static typing.

With this combination, you can catch errors early, improve code maintainability, and boost developer productivity. It ensures your app is scalable and robust from the start. It not only enhances collaboration among teams but also future-proofs your codebase.

So, want help with building the best cross-platform apps? Then consult with our top React Native professionals today!

author
Vish Shah is Technical Consultant at WPWeb Infotech since 2015. He has vast experience in working with various industries across the globe. He writes about the latest web development technologies and shares his thoughts regularly.
Leave a comment