React Tutorial
Estimated reading: 4 minutes 301 views

React with TypeScript – Build Safer & Scalable Apps (2025 Guide)


Introduction – Why Use TypeScript with React?

TypeScript enhances React development by adding static typing, autocomplete, and compile-time error detection. It enables:

  • Safer code through type checking
  • Smarter developer tooling and IDE support
  • Better documentation and component contracts

TypeScript is now the industry standard for large React apps at companies like Microsoft, Meta, and Shopify.

In this guide, you’ll learn:

  • How to set up a React + TypeScript project
  • Type your components, props, state, events, and hooks
  • Use generics, enums, and utility types
  • Best practices and tips for scalable TSX code

1. Setup – Create a React + TypeScript Project

With Vite (Recommended):

npm create vite@latest my-app -- --template react-ts

With Create React App (CRA):

npx create-react-app my-app --template typescript

You’ll get .tsx support and tsconfig.json automatically.


2. Basic Component Typing

Functional Component with Props:

type GreetingProps = {
  name: string;
  age?: number; // optional prop
};

const Greeting: React.FC<GreetingProps> = ({ name, age }) => (
  <p>Hello, {name}! {age && `Age: ${age}`}</p>
);

Type safety for consumers
Autocomplete for props in JSX


3. useState & useEffect Typing

const [count, setCount] = useState<number>(0);
const [user, setUser] = useState<User | null>(null);

useEffect(() => {
  console.log('Count changed:', count);
}, [count]);

Always annotate complex types like null, objects, or arrays
Optional: let TypeScript infer types for primitives


4. Typing Events in React

Input Change Event:

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  setValue(e.target.value);
};

Form Submit:

const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
  e.preventDefault();
  // submit logic
};

Use React.*Event for DOM event types


5. Children and FC Typing

type CardProps = {
  children: React.ReactNode;
};

const Card: React.FC<CardProps> = ({ children }) => (
  <div className="card">{children}</div>
);

Enables Card to wrap any nested JSX content


6. Typing useRef and useReducer

useRef:

const inputRef = useRef<HTMLInputElement>(null);

useReducer:

type State = { count: number };
type Action = { type: 'increment' | 'decrement' };

const reducer = (state: State, action: Action): State => {
  switch (action.type) {
    case 'increment': return { count: state.count + 1 };
    case 'decrement': return { count: state.count - 1 };
  }
};

const [state, dispatch] = useReducer(reducer, { count: 0 });

Type-safe reducer patterns for complex state logic


7. Typing Custom Hooks

function useToggle(initial: boolean): [boolean, () => void] {
  const [value, setValue] = useState(initial);
  const toggle = () => setValue(v => !v);
  return [value, toggle];
}

Explicit return types improve reusability
Encourages better API design


8. TypeScript Utility Types

Utility TypeDescriptionExample
Partial<T>Makes all properties optionalPartial<User>
Pick<T, K>Selects a subset of properties`Pick<User, ‘name’
Omit<T, K>Excludes properties from typeOmit<User, 'password'>
Record<K, T>Creates an object type with keys KRecord<string, boolean>
Readonly<T>Makes fields immutableReadonly<User>

Great for forms, settings, feature toggles, etc.


9. Best Practices for React + TypeScript

Use .tsx for all components
Define Props types near the component
Avoid anyβ€”use unknown or strong typing instead
Use interface or type consistently (prefer type for components)
Type your API responses or use Zod/Yup for runtime validation
Use enum or union types for fixed values (e.g., button variants)


Summary – Recap & Next Steps

Using TypeScript with React provides robust typing, better tooling, and fewer bugs in the long run. It’s ideal for scalable apps, component libraries, and enterprise teams.

Key Takeaways:

  • Type props, state, events, and hooks for full coverage
  • Prefer type-safe utilities over loose typing
  • Avoid any and use interface or type consistently
  • Type custom hooks and async APIs for reliability
  • Use VS Code and ESLint to maximize productivity

Real-World Relevance:
React + TypeScript is used by Meta, Microsoft, Atlassian, and top open-source libraries for their component systems and production codebases.


FAQ Section

Should I use interface or type for props?
Both work. Use type for function signatures and union types; interface for extending object shapes.


How do I type API responses?
Use type User = Awaited<ReturnType<typeof fetchUser>> or tools like Zod to validate and infer types.


Is TypeScript required for React?
No, but it’s highly recommended for better safety, maintainability, and IDE support.


Can I use React Testing Library with TypeScript?
Yes! Most RTL APIs are fully typed. Add @testing-library/jest-dom for extended matchers.


How do I type dynamic component props?
Use union or discriminated unions for conditional props:

type Props = { type: 'text'; value: string } | { type: 'checkbox'; checked: boolean };

Share Now :
Share

🟦 React with TypeScript

Or Copy Link

CONTENTS
Scroll to Top