React - TypeScript with React

Overview

Estimated time: 25–35 minutes

Add type safety to your components, props, events, state, and reducers using TypeScript. We compile TS in-browser with Babel.

Prerequisites

  • Basic TypeScript (interfaces, unions, generics) helpful but not required.

Try it: Typed Props and Events

View source
type GreetingProps = { name: string };
function Greeting({ name }: GreetingProps){
  return <h3>Hello, {name}!</h3>;
}
function App(){
  const [text, setText] = React.useState('');
  function onChange(e: React.ChangeEvent){
    setText(e.target.value);
  }
  return (
    <div>
      <Greeting name={text || 'World'} />
      <input value={text} onChange={onChange} placeholder="Type your name" />
    </div>
  );
}
ReactDOM.createRoot(document.getElementById('try-ts')).render(<App />);

Try it: Typed Reducer

View source
type State = { count: number };
type Action = { type: 'inc'; step: number } | { type: 'reset'; to: number };
function reducer(s: State, a: Action): State {
  switch (a.type){
    case 'inc': return { count: s.count + a.step };
    case 'reset': return { count: a.to };
  }
}
function Counter(){
  const [state, dispatch] = React.useReducer(reducer, { count: 0 });
  return (
    <div>
      Count: {state.count}
      <button onClick={() => dispatch({type:'inc', step:1})}>+1</button>
      <button onClick={() => dispatch({type:'reset', to:0})} style={{marginLeft:8}}>Reset</button>
    </div>
  );
}
ReactDOM.createRoot(document.getElementById('try-ts-2')).render(<Counter />);

Syntax primer

  • Props: type Props = { ... } and destructure in component signature.
  • Events: React.ChangeEvent<HTMLInputElement> for inputs.
  • State: useState<T>() generics; reducers with typed State and Action.

Common pitfalls

  • Using any everywhere defeats TypeScript’s benefits—prefer precise types.
  • Overly complex generics reduce readability; start simple, refine later.

Checks for Understanding

  1. How do you type an input change handler in React + TypeScript?
  2. What are the benefits of typed reducers?
Show answers
  1. (e: React.ChangeEvent<HTMLInputElement>) captures event typing for inputs.
  2. They prevent invalid actions/state and improve maintainability through explicit types.

Exercises

  1. Define a User interface and type a component that renders a user card.
  2. Add a discriminated union to the reducer and handle a new action.
  3. Introduce a typed Context for configuration and consume it in a component.