Skip to content

React TypeScript

Prerequisite

Awesome TypeScript resources

Setup TypeScript with React

Prerequisites

familiarity with TypeScript Types (2ality’s guide is helpful. If you’re an absolute beginner in TypeScript, check out chibicode’s tutorial.)

React + TypeScript Starter Kits

Cloud setups:

Local dev setups:

  • Create React App: npx create-react-app name-of-app --template typescript will create in new folder
  • Next.js: npx create-next-app -e with-typescript will create in your current folder

Getting Started with React TypeScript Template

  1. Create app using

    Terminal window
    npx create-react-app my-app --template typescript
  2. Enter to the directory

    Terminal window
    cd my-app

    You will see the project structure like this:

    my-app
    ├── package.json
    ├── public
    │   ├── favicon.ico
    │   ├── index.html
    │   ├── logo192.png
    │   ├── logo512.png
    │   ├── manifest.json
    │   └── robots.txt
    ├── README.md
    ├── src
    │   ├── App.css
    │   ├── App.test.tsx
    │   ├── App.tsx
    │   ├── index.css
    │   ├── index.tsx
    │   ├── logo.svg
    │   ├── react-app-env.d.ts
    │   ├── reportWebVitals.ts
    │   └── setupTests.ts
    ├── tsconfig.json
    └── yarn.lock
  3. Run React project using

    yarn start

VS Code Extensions

Import React

Add allowSyntheticDefaultImports": true in your tsconfig.json, you can use more familiar imports:

import React from 'react';
import ReactDOM from 'react-dom';

Basic React with TypeScript

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) => <div>{message}</div>;
// you can choose annotate the return type so an error is raised if you accidentally return some other type
const App = ({ message }: AppProps): JSX.Element => <div>{message}</div>;
// you can also inline the type declaration; eliminates naming the prop types, but looks repetitive
const App = ({ message }: { message: string }) => <div>{message}</div>;

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

Hooks

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

useState

Type inference works very well for simple values:

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

useEffect

When using useEffect, take care not to return anything other than a function or undefined, otherwise both TypeScript and React will yell at you. This can be subtle when using arrow functions:

function DelayedEffect(props: { timerMs: number }) {
const { timerMs } = props;
useEffect(
() =>
setTimeout(() => {
/* do stuff */
}, timerMs),
[timerMs]
);
// bad example! setTimeout implicitly returns a number
// because the arrow function body isn't wrapped in curly braces
return null;
}

Asynchronous useEffect

อันนี้เป็นตัวอย่างการ fetch ข้อมูลครั้งแรกเมื่อ Component ถูกโหลดนะครับ

function AsyncUseEffect() {
useEffect(
() => asyncFetch(),
[]
);
const asyncFetch = async () => {
const result = await fetch("https://jsonplaceholder.typicode.com/todos/1");
console.log(result);
}
return null;
}

For more Hook usage and complex type: https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/hooks

Mostly Used Prop Type

interface AppProps {
children: React.ReactNode; // accepts everything
style?: React.CSSProperties; // to pass through style props
onChange?: React.FormEventHandler<HTMLInputElement>; // form events! the generic parameter is the type of event.target
// more info: https://react-typescript-cheatsheet.netlify.app/docs/advanced/patterns_by_usecase/#wrappingmirroring
}

Useful React Prop Type Examples

interface AppProps {
children1: JSX.Element; // bad, doesnt account for arrays
children2: JSX.Element | JSX.Element[]; // meh, doesn't accept strings
children3: React.ReactChildren; // despite the name, not at all an appropriate type; it is a utility
children4: React.ReactChild[]; // better, accepts array children
children: React.ReactNode; // best, accepts everything (see edge case below)
functionChildren: (name: string) => React.ReactNode; // recommended function as a child render prop type
style?: React.CSSProperties; // to pass through style props
onChange?: React.FormEventHandler<HTMLInputElement>; // form events! the generic parameter is the type of event.target
// more info: https://react-typescript-cheatsheet.netlify.app/docs/advanced/patterns_by_usecase/#wrappingmirroring
props: Props & React.ComponentPropsWithoutRef<"button">; // to impersonate all the props of a button element and explicitly not forwarding its ref
props2: Props & React.ComponentPropsWithRef<MyButtonWithForwardRef>; // to impersonate all the props of MyButtonForwardedRef and explicitly forwarding its ref
}

Ref