MCPcopy
hub / github.com/typescript-cheatsheets/react

github.com/typescript-cheatsheets/react @main sqlite

repository ↗ · DeepWiki ↗
9 symbols 29 edges 4 files 1 documented · 11%
README

React TypeScript Cheatsheet

Cheatsheet for using React with TypeScript.


react + ts logo

Web docs | Contribute! | Ask!

:wave: This repo is maintained by @eps1lon and @filiptammergard. We're so happy you want to try out React with TypeScript! If you see anything wrong or missing, please file an issue! :+1:


All Contributors | Discord

The Cheatsheet is focused on helping React devs use TypeScript effectively:

  • Opinionated best practices and copy+pastable examples.
  • Covers basic TS types and setup, plus advanced usage of generic types for people writing reusable type utilities and React+TS libraries.
  • Advice for contributing to DefinitelyTyped.

Cheatsheet

Table of Contents

Expand Table of Contents

Introduction

Prerequisites

You can use this cheatsheet for reference at any skill level, but basic understanding of React and TypeScript is assumed. Here is a list of prerequisites:

In the cheatsheet we assume you are using the latest versions of React and TypeScript.

React and TypeScript starter kits

React has documentation for how to start a new React project with some of the most popular frameworks. Here's how to start them with TypeScript:

  • Next.js: npx create-next-app@latest --ts
  • Remix: npx create-remix@latest
  • Gatsby: npm init gatsby --ts
  • Expo: npx create-expo-app -t with-typescript

If you just want a client-side single-page app without a framework, Vite is the most common choice:

  • Vite: npm create vite@latest my-app -- --template react-ts

Try React and TypeScript online

There are some tools that let you run React and TypeScript online, which can be helpful for debugging or making sharable reproductions.

Getting Started

Function Components

These can be written as normal functions that take a props argument and return a JSX element.

// Declaring type of props - see "Typing Component Props" for more examples
type AppProps = {
  message: string;
}; /* use `interface` if exporting so that consumers can extend */

// Easiest way to declare a Function Component; return type is inferred.
const App = ({ message }: AppProps) => 

{message}

;

// You can choose to annotate the return type so an error is raised if you accidentally return some other type
const App = ({ message }: AppProps): React.JSX.Element => 

{message}

;

// You can also inline the type declaration; eliminates naming the prop types, but looks repetitive
const App = ({ message }: { message: string }) => 

{message}

;

// Alternatively, you can use `React.FunctionComponent` (or `React.FC`), if you prefer.
// With latest React types and TypeScript 5.1. it's mostly a stylistic choice, otherwise discouraged.
const App: React.FunctionComponent<{ message: string }> = ({ message }) => (


{message}


);
// or
const App: React.FC<AppProps> = ({ message }) => 

{message}

;

Tip: You might use Paul Shen's VS Code Extension to automate the type destructure declaration (incl a keyboard shortcut).

Why is React.FC not needed? What about React.FunctionComponent/React.VoidFunctionComponent?

You may see this in many React+TypeScript codebases:

const App: React.FunctionComponent<{ message: string }> = ({ message }) => (


{message}


);

However, the general consensus today is that React.FunctionComponent (or the shorthand React.FC) is not needed. If you're still using React 17 or TypeScript lower than 5.1, it is even discouraged. This is a nuanced opinion of course, but if you agree and want to remove React.FC from your codebase, you can use this jscodeshift codemod.

Some differences from the "normal function" version:

  • React.FunctionComponent is explicit about the return type, while the normal function version is implicit (or else needs additional annotation).

  • It provides typechecking and autocomplete for static properties like displayName, propTypes, and defaultProps.

  • Note that there are some known issues using defaultProps with React.FunctionComponent. See this issue for details. We maintain a separate defaultProps section you can also look up.

  • In the future, it may automatically mark props as readonly, though that's a moot point if the props object is destructured in the parameter list.

In most cases it makes very little difference which syntax is used, but you may prefer the more explicit nature of React.FunctionComponent.

Hooks

Hooks are supported in @types/react from v16.8 up.

useState

Type inference works very well for simple values:

const [state, setState] = useState(false);
// `state` is inferred to be a boolean
// `setState` only takes booleans

If you need to use a complex type that you've relied on inference for, you can use typeof to capture the inferred type.

However, many hooks are initialized with null-ish default values, and you may wonder how to provide types. Explicitly declare the type, and use a union type:

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

// later...
setUser(newUser);

You can also use type assertions if a state is initialized soon after setup and always has a value after:

const [user, setUser] = useState<User>({} as User);

// later...
setUser(newUser);

This temporarily "lies" to the TypeScript compiler that {} is of type User. You should follow up by setting the user state — if you don't, the rest of your code may rely on the fact that user is of type User and that may lead to runtime errors.

useCallback

You can type the useCallback just like any other function.

const memoizedCallback = useCallback(
  (param1: string, param2: number) => {
    console.log(param1, param2)
    return { ok: true }
  },
  [...],
);
/**
 * VSCode will show the following type:
 * const memoizedCallback:
 *  (param1: string, param2: number) => { ok: boolean }
 */

Note that for React < 18, the function signature of useCallback typed arguments as any[] by default:

function useCallback<T extends (...args: any[]) => any>(
  callback: T,
  deps: DependencyList,
): T;

In React >= 18, the function signature of useCallback changed to the following:

function useCallback<T extends Function>(callback: T, deps: DependencyList): T;

Therefore, the following code will yield "Parameter 'e' implicitly has an 'any' type." error in React >= 18, but not <17.

// @ts-expect-error Parameter 'e' implicitly has 'any' type.
useCallback((e) => {}, []);
// Explicit 'any' type.
useCallback((e: any) => {}, []);

useReducer

You can use Discriminated Unions for reducer actions. Don't forget to define the return type of reducer, otherwise TypeScript will infer it.

import { useReducer } from "react";

const initialState = { count: 0 };

type ACTIONTYPE =
  | { type: "increment"; payload: number }
  | { type: "decrement"; payload: string };

function reducer(
  state: typeof initialState,
  action: ACTIONTYPE,
): typeof initialState {
  switch (action.type) {
    case "increment":
      return { count: state.count + action.payload };
    case "decrement":
      return { count: state.count - Number(action.payload) };
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({ type: "decrement", payload: "5" })}>
        -
      </button>
      <button onClick={() => dispatch({ type: "increment", payload: 5 })}>
        +
      </button>
    </>
  );
}

[View in the TypeScript Playground](https://ww

Core symbols most depended-on inside this repo

updateSectionWith
called by 12
genReadme.mjs
generateContentForSection
called by 2
genReadme.mjs
getFenceForSection
called by 2
genReadme.mjs
getFence
called by 2
genReadme.mjs
readContentFromPath
called by 1
genReadme.mjs
withHeadingContext
called by 1
genReadme.mjs
copyFile
called by 1
copyFile.js
main
called by 0
genReadme.mjs

Shape

Function 9

Languages

TypeScript100%

Modules by API surface

genReadme.mjs7 symbols
website/src/pages/index.tsx1 symbols
copyFile.js1 symbols

Dependencies from manifests, versioned

@docusaurus/core3.10.1 · 1×
@docusaurus/plugin-client-redirects3.10.1 · 1×
@docusaurus/preset-classic3.10.1 · 1×
@docusaurus/tsconfig3.10.1 · 1×
@docusaurus/types3.10.1 · 1×
@types/react19.2.0 · 1×
@types/react-dom19.2.0 · 1×
classnames2.5.1 · 1×
front-matter4.0.2 · 1×
markdown-toc1.2.0 · 1×
prettier3.8.3 · 1×
prism-react-renderer2.4.1 · 1×

For agents

$ claude mcp add react \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact