DEV Community

Cover image for Typescript to Know for React
Ndeye Fatou Diop
Ndeye Fatou Diop

Posted on • Originally published at frontendjoy.com

Typescript to Know for React

📚 Download my FREE 101 React Tips And Tricks Book for a head start.


Two weeks ago, I stumbled upon this post on Reddit: Should I learn React with TypeScript or JavaScript?

I see these posts all the time—and honestly, it breaks my heart 🥲

If you’re a React dev still using JavaScript, you’re making your life harder.

The time you spend learning TypeScript will 100% pay off in the time you save debugging weird bugs.

So here’s a guide to help you make the switch.

Just the essentials. No fluff 😉.


How TypeScript works

TypeScript adds extra syntax on top of JavaScript to help catch errors early—before they crash your app.

It compiles to JavaScript in the end.

The best part? You can slowly migrate to TypeScript.

Follow this guide for more.


Why you should switch to TypeScript ASAP

Here’s why I think it’s a no-brainer:

Benefit #1: Catch bugs before they reach production

This JavaScript code looks fine… until it explodes:

function printFirstChar(users, userIndex) {
  const name = users[userIndex];
  console.log(name[0]);
}

const users = ['Fatou', 'Bob'];

printFirstChar(users, 5); // ❌ Runtime error: Cannot read properties of undefined
Enter fullscreen mode Exit fullscreen mode

Here’s the TypeScript version:

function printFirstChar(users: string[], userIndex: number) {
  const name = users[userIndex];

  if (name != null) {
    console.log(name[0]);
  }
}
Enter fullscreen mode Exit fullscreen mode

TypeScript doesn’t fix your logic, but it gives you early warnings like “hey, this might be undefined 👀”


Benefit #2: Get autocompletion with libraries

Especially useful when you're exploring a new library.

If that library has TypeScript types, you can get autocompletion inside most editors.


Benefit #3: Make your code more resilient to changes

When you type things properly, TypeScript acts like a safety net.

For example:

Without TypeScript, this code can break without you noticing.

function getLabel(status) {
  switch (status) {
    case 'idle':
      return 'Idle';
    case 'loading':
      return 'Loading';
    case 'success':
      return 'Success';
  }
}

getLabel('loading'); // ✅ works

// Months later...

getLabel('error'); // ❌ returns undefined, but no JS error
Enter fullscreen mode Exit fullscreen mode

With TypeScript, you need to handle changes.

type Status = 'idle' | 'loading' | 'success';

function getLabel(status: Status): string {
  switch (status) {
    case 'idle':
      return 'Idle';
    case 'loading':
      return 'Loading';
    case 'success':
      return 'Success';
    case 'error':
      return 'Error';
  }
}

// Months later...
type Status = 'idle' | 'loading' | 'success' | 'error'; // added 'error'

// ✅ TypeScript will show an error for the `getLabel` function: "Not all code paths return a value"
Enter fullscreen mode Exit fullscreen mode

If you forget to handle a case, TypeScript yells at you. And that’s precisely what you want 😄.

TypeScript error when we forget to handle a case


The TypeScript concepts you need for React

Let’s cover the bare minimum to get started.


✅ Types

Types let you describe the shape of your data and enforce it.

There are native types in TypeScript, and types defined by users.

Native types

These types come by default.

const name = 'Ada'; // string
const age: number = 31; // number
const isActive = true; // boolean
const scores: number[] = [90, 85, 100]; // number[]
Enter fullscreen mode Exit fullscreen mode

💡 In some of the examples above, I typed values explicitly (like const age: number = 31).

You don’t need to do that in real code—TypeScript can infer the types by looking at the values.

Custom types

You can create new types using the native types.

type User = {
  id: number;
  name: string;
};

const user: User = {
  id: 1,
  name: 'Fatou',
};
Enter fullscreen mode Exit fullscreen mode

❌ Avoid any

Unless you’re in the middle of a migration, don’t use any.

It’s JavaScript in disguise.

Use unknown instead—it forces you to check the type before using it.

// ❌ Bad: no warning, crashes at runtime
function logLength(value: any) {
  console.log(value.length);
}

logLength(123);

// ✅ Safer
function logLength(value: unknown) {
  if (typeof value === 'string' || Array.isArray(value)) {
    console.log(value.length);
  }
}

// ✅✅ Better: use an explicit type
function logLength(value: string | ArrayLike<unknown>){
  console.log(value.length);
}
Enter fullscreen mode Exit fullscreen mode

🧩 Union & intersection types

Unions let a value be one of many types.

type Status = 'idle' | 'loading' | 'error';

let currentStatus: Status = 'idle';
Enter fullscreen mode Exit fullscreen mode

Intersections combine multiple types into one.

type Name = { name: string };
type Age = { age: number };

type Person = Name & Age;

const person: Person = { name: 'Ada', age: 30 };
Enter fullscreen mode Exit fullscreen mode

🧱 Interfaces

Interfaces define the structure of an object.

interface User {
  name: string;
  age: number;
}
Enter fullscreen mode Exit fullscreen mode

You can extend interfaces:

interface Admin extends User {
  role: string;
}
Enter fullscreen mode Exit fullscreen mode

When to use type vs interface? Doesn’t matter much.

But here’s an interesting guide:

👉 Type vs Interface: Which Should You Use?


🔁 Generics

Generics let you write reusable types with flexible data.

Let’s say you’re typing an API response.

Without generics:

type UserResponse = {
  status: number;
  data: User;
  error?: string;
};

type ProductResponse = {
  status: number;
  data: Product;
  error?: string;
};
Enter fullscreen mode Exit fullscreen mode

That’s a lot of repetition.

With generics:

type ApiResponse<T> = {
  status: number;
  data: T;
  error?: string;
};

type UserResponse = ApiResponse<User>;
type ProductResponse = ApiResponse<Product>;
Enter fullscreen mode Exit fullscreen mode

You can use generics in functions too:

function wrap<T>(value: T): T[] {
  return [value];
}

wrap(42); // type: number[]
wrap('hi'); // type: string[]
Enter fullscreen mode Exit fullscreen mode

I like to think of generics like function parameters—but for types 😉.


🔧 Function types

You can type function parameters and return values.

You always need to type the parameters, but don’t need to type the returned value every time.

// This works
function add(a: number, b: number): number {
  return a + b;
}

// This also works: you don't need to type the returned value
function add(a: number, b: number) {
  return a + b; // inferred as number
}
Enter fullscreen mode Exit fullscreen mode

You can also type the function variable:

const add: (a: number, b: number) => number = (a, b) => a + b;
Enter fullscreen mode Exit fullscreen mode

Depending on the context, you may want to type the return type. When in doubt, type the return type.

You can learn more about return types here:


How to use TypeScript with React

Props

Props are just objects. Type them like any other object.

With type:

type GreetingProps = {
  name: string;
};

function Greeting({ name }: GreetingProps) {
  return <p>Hello {name}</p>;
}
Enter fullscreen mode Exit fullscreen mode

With interface :

interface GreetingProps {
  name: string;
}

function Greeting({ name }: GreetingProps) {
  return <p>Hello {name}</p>;
}
Enter fullscreen mode Exit fullscreen mode

State

useState accepts a generic type, but TypeScript can also infer it.

const [count, setCount] = useState(0); // inferred as number
Enter fullscreen mode Exit fullscreen mode

But if it can’t, be explicit:

const [user, setUser] = useState<{ id: number; name: string } | null>(null);
Enter fullscreen mode Exit fullscreen mode

Component variables and functions

Just like normal TypeScript:

const users: User[] = [{name: "Fatou", age: 31}, {name: "Bob", age: 25} ];
const age = 30; // inferred as number
Enter fullscreen mode Exit fullscreen mode

When you have some functions like event handlers, you can hover over the DOM elements to see the types to use.

const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
  console.log('Clicked!', event);
};

// Or:
const handleClick: React.MouseEventHandler<HTMLButtonElement> = (event) => {
  console.log('Clicked!', event);
};
Enter fullscreen mode Exit fullscreen mode

Re-using types across components

You can extend or combine types/interfaces to avoid duplication.

With interfaces:

interface ButtonProps {
  label: string;
}

interface IconButtonProps extends ButtonProps {
  icon: React.ReactNode;
}
Enter fullscreen mode Exit fullscreen mode

With union types:

type ButtonProps = {
  label: string;
};

type IconButtonProps = ButtonProps & {
  icon: React.ReactNode;
};
Enter fullscreen mode Exit fullscreen mode

Hooks

Hooks are just functions, so you can use the same TypeScript tools that apply to functions.

Native hooks

Pretty much all the native hooks have generic params.

const [count, setCount] = useState<number>(0);
// or let TS infer:
const [count, setCount] = useState(0);

const inputRef = useRef<HTMLInputElement>(null);

const [state, dispatch] = useReducer(
  (state: number, action: 'inc' | 'dec') => {
    switch (action) {
      case 'inc':
        return state + 1;
      case 'dec':
        return state - 1;
    }
  },
  0
);
Enter fullscreen mode Exit fullscreen mode

Custom hooks

function useToggle(initial: boolean): [boolean, () => void] {
  const [state, setState] = useState(initial);
  const toggle = () => setState((prev) => !prev);
  return [state, toggle];
}

const [isOpen, toggleOpen] = useToggle(false);
Enter fullscreen mode Exit fullscreen mode

Where to learn more

If you want to go deeper with TypeScript, here are some great resources to explore:

  • 🧠 TypeScript Official Docs: The best place to start. It’s clear, well-structured, and packed with examples. Also includes a playground to test things out.

  • 🎯 Total TypeScript: A fantastic site by Matt Pocock—especially for React devs.

    It has a free beginner course, advanced patterns, and many real-world examples.

  • TypeScript Style Guide: Short, practical tips on how to write clean and consistent TypeScript code. Highly recommended once you start building real apps.

  • 🧩 Type Challenges: A collection of TypeScript puzzles—from beginner to insane. Great if you learn best by solving problems and want to flex your type system skills.

  • 📘 Effective TypeScript: A book + blog by Dan Vanderkam. More advanced, but teaches you how to write better TypeScript. Worth it once you know the basics.

  • ⚛️ React TypeScript Cheatsheets: Tailored for React devs. Covers everything from typing components to context and hooks. Very beginner-friendly, and super helpful as a quick reference.

💡 Make sure to also check out the TypeScript section of my 101 React Tips & Tricks post 😉.


Summary

Using TypeScript with React is one of the best upgrades you can make.

It helps you catch bugs early, gives you better tooling, and makes your code easier to maintain.

The best part? You don’t need to learn everything up front. Start with the basics—types, interfaces, generics—and grow from there.

Many examples are online if you get stuck, and AI tools can help you unblock fast.

Let me know if you have any questions 🙂.

<iframe src="https://embeds.beehiiv.com/4b52f101-5150-4e42-abc6-28785fdd68cd" data-test-id="beehiiv-embed" width="100%" height="320" frameborder="0" scrolling="no" style="border-radius: 4px; border: 2px solid #e5e7eb; margin: 0; background-color: transparent;"></iframe>
Enter fullscreen mode Exit fullscreen mode

Section Divider

That's a wrap 🎉.

Leave a comment 📩 to join the discussion.

And don't forget to drop a "💖🦄🔥".

If you're learning React, download my 101 React Tips & Tricks book for FREE.

If you like articles like this, join my FREE newsletter, FrontendJoy.

If you want daily tips, find me on X/Twitter or Bluesky.

Top comments (15)

Collapse
 
nevodavid profile image
Nevo David

But I like it, learning TypeScript for React feels like adding training wheels when riding a new bikemakes the trip smoother and you fall less; but what happens if you never take the training wheels off?

Collapse
 
_ndeyefatoudiop profile image
Ndeye Fatou Diop

I really like the analogy!
The nice thing here is that you never have to take the wheels off (except maybe in interviews and I agree it is painful in that case 😅)

Collapse
 
gnrlbzik profile image
Alesei N

I will be honest, I like the idea of this article a lot.

But maybe improve first example for "Benefit #1: Catch bugs before they reach production" that if statement in typescript snippet could of been as easily used in javascript example with out typescript reference... Nothing about this screams typescript specific... change, so maybe reword it so it is obvious, that this IF statement was added after typescript suggested it?

Might be just me, but thats how I read it at first.

Collapse
 
_ndeyefatoudiop profile image
Ndeye Fatou Diop

Thanks a lot for the input!
So name[0] will throw in JS but in TS, you will automatically see the warning in the IDE :)
Does it make more sense?

Collapse
 
gnrlbzik profile image
Alesei N

Yeah, anything to remove magic, and assumption, especially for those who otherwise do not know better.

Collapse
 
jutionck profile image
Jution Candra Kirana

Thank you, very helpful for learning more about ts

Collapse
 
jutionck profile image
Jution Candra Kirana
Collapse
 
kader198 profile image
Abdel Kader Maguiraga

Thanks for sharing

Collapse
 
_ndeyefatoudiop profile image
Ndeye Fatou Diop

Glad you like it ❤️

Collapse
 
anmolbaranwal profile image
Anmol Baranwal

Some cool tips! You should share it on Daily (squads)... this type of tutorial based articles are always super valuable.

Collapse
 
_ndeyefatoudiop profile image
Ndeye Fatou Diop

Thanks a lot! What are daily squads?

Collapse
 
anmolbaranwal profile image
Anmol Baranwal

Check this: app.daily.dev/squads/discover

Communities on daily.dev based on interests.

Thread Thread
 
_ndeyefatoudiop profile image
Ndeye Fatou Diop

Oh thanks a lot for sharing! I do see those but I find it hard sometimes to have the right to post 😅. Do you recommend one?

Thread Thread
 
anmolbaranwal profile image
Anmol Baranwal

It totally depends on the topic but you can definitely share it in my squad. That’s where I post all of my articles on Daily.

I can’t really comment on the reach, since the algorithm changes from time to time... so try and see which squads give you better results.

Thread Thread
 
_ndeyefatoudiop profile image
Ndeye Fatou Diop

Thanks a lot for sharing these 😃

Some comments may only be visible to logged-in visitors. Sign in to view all comments.