React Native TypeScript

TypeScript adds a safety net to JavaScript. It lets you describe the shape of every value, and the editor warns you about mistakes before the app runs. A misspelled prop, a missing field, or a wrong data type shows up as a red underline while you type. Large teams and long-lived apps rely on this early feedback.

The Core Idea

JavaScript                      TypeScript
─────────────────               ─────────────────────────
Run app                         Write code
Tap button                      Editor flags the error
Crash appears                   Fix it right away
Hunt for the cause              Run app, no crash

TypeScript code compiles down to plain JavaScript. The phone never sees the types. They exist only to protect you during development.

Start a TypeScript Project

npx create-expo-app my-app --template blank-typescript

Existing projects convert step by step. Add a tsconfig.json, install the type packages, and rename files from .js to .tsx one at a time. Files with JSX use .tsx. Plain logic files use .ts.

Basic Types

const name: string = 'Asha';
const age: number = 24;
const isMember: boolean = true;
const scores: number[] = [90, 85, 70];

TypeScript guesses types from the starting value, so explicit labels are often optional. const age = 24 already counts as a number.

Describe Data with Types and Interfaces

An interface names the shape of an object. Think of it as a form template with labeled blanks.

interface Product {
  id: number;
  title: string;
  price: number;
  inStock?: boolean;   // the question mark marks an optional field
}

const phone: Product = { id: 1, title: 'Phone', price: 299 };
Product
├── id       : number
├── title    : string
├── price    : number
└── inStock? : boolean (optional)

Type Component Props

Props are the inputs of a component. Describe them so callers cannot forget a value or pass the wrong kind.

import { Text, TouchableOpacity } from 'react-native';

interface PrimaryButtonProps {
  label: string;
  onPress: () => void;
  disabled?: boolean;
}

export function PrimaryButton({ label, onPress, disabled = false }: PrimaryButtonProps) {
  return (
    <TouchableOpacity onPress={onPress} disabled={disabled}>
      <Text>{label}</Text>
    </TouchableOpacity>
  );
}

Using <PrimaryButton label={42} /> now triggers an error, since a label must be text and onPress is missing.

Type State

Give useState a type in angle brackets when the starting value cannot reveal the full shape.

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

The User | null notation is a union. The value is either a user or nothing. TypeScript forces you to check for null before reading its fields.

if (user) {
  console.log(user.name);   // safe: user exists here
}

Union Types for Fixed Choices

type Status = 'idle' | 'loading' | 'success' | 'error';
const [status, setStatus] = useState<Status>('idle');

setStatus('done');   // error: 'done' is not an allowed value

Type Style Objects

React Native ships helper types so style objects receive autocomplete and checks.

import { StyleSheet, ViewStyle, TextStyle } from 'react-native';

const styles = StyleSheet.create({
  card: { padding: 16, borderRadius: 8 } as ViewStyle,
});

Type Navigation

Declare the list of screens and the data each one expects. Navigation calls then become safe.

type RootStackParams = {
  Home: undefined;
  Details: { productId: number };
};

navigation.navigate('Details', { productId: 7 });   // valid
navigation.navigate('Details');                      // error: missing productId

Type API Responses

const loadProducts = async (): Promise<Product[]> => {
  const res = await fetch('https://example.com/products');
  const data: Product[] = await res.json();
  return data;
};

Avoid the any Type

The type any switches checking off. Use it rarely. The type unknown offers a safer choice, since it forces a check before use.

Helpful Habits

  • Turn on "strict": true in tsconfig.json
  • Keep shared interfaces in a types folder
  • Let TypeScript infer simple types
  • Read error messages slowly, since they usually name the exact problem

Summary

TypeScript catches mistakes while you write. Describe objects with interfaces, type component props and state, and use unions for fixed choices. Typed navigation and typed API responses prevent whole families of runtime errors, and strict mode gives the strongest protection.