TypeScript in React

Here are some notes about TypeScript in React.

They come from the book The Road to React by Robin Wieruch.

Setup

TypeScript is a programming language developed by Microsoft that adds static typing with optional type annotations to JavaScript.

  1. install TypeScript and its dependencies:
    npm install typescript @types/react @types/react-dom --save-dev
    
  2. add TypeScript configurations files
    touch tsconfig.json tsconfig.node.json
    
    • one for the browser environment
    • one for the Node environment
  3. rename JavaScript files:
    mv src/main.jsx src/main.tsx
    mv src/App.jsx src/App.tsx
    
  4. change references in HTML files (.jsx -> .tsx)
  5. install a TypeScript plugin for your IDE to see red lines under all the values where TypeScript definitions are missing

Assertion

Assertion with as (e.g. when you are certain there is an HTML element):

document.getElementById('root') as HTMLElement

Type safety

A function's input (and optionally output) has to be type safe:

const useStorageState = (
  key: string,
  initialState: string
): [string, (newValue: string) => void] => {
  …
}

Here, useStorageState:

  • expect two arguments as string primitives
  • return an array with:
    • a first value of type string (the current state)
    • a second value of type function (the state updater function)
      • that returns nothing (void)
      • and takes a new state (newValue) of type string

Type inference works most of the time for React hooks. TypeScript can work out a variable's type without it having a type annotation:

const [value, setValue] = React.useState('React');
// value is inferred to be a string
// setValue only takes a string as argument

TypeScript generics

TypeScript generics let you specify a type that can change depending on the usage:

type User<StatusOptions> = {
  name: string;
  status: StatusOptions;
};

const user: User<'online' | 'offline'>;
const user: User<'online' | 'offline' | 'idle'>;

StatusOptions is called a type variable and User is said to be a generic type.

It's the TypeScript equivalent of functions, a JavaScript-like syntax would look like this:

type User = (StatusOption) => {
  return {
    name: string;
    status: StatusOptions;
  }
}

A very common usage is having a function that returns the same type as its argument:

function identity<ArgType>(arg: ArgType): ArgType {
  return arg;
}

In React, useState itself takes a type variable called S. So, if the initial state would be null initially, we can use:

const [value, setValue] = React.useState<string | null>(null);
// value has to be either a string or null
// setValue only takes a string or null as argument

Defining types outside of components

type Story = {
  objectID: string;
  url: string;
  title: string;
  author: string;
  num_comments: number;
  points: number;
};

type ItemProps = {
  item: Story;
  onRemoveItem: (item: Story) => void;
};

const Item = ({ item, onRemoveItem }: ItemProps) => (
  …
);

item is of type Story and onRemoveItem takes an item of type Story as an argument and returns nothing.

Alternative way with React.FunctionComponent (or React.FC):

const Item: React.FC<ItemProps> = ({ item, onRemoveItem }) => (
  <li>
    …
  </li>
);

React+TypeScript Cheatsheets

React+TypeScript Cheatsheets.

Avant Performance in React Après Difference between null and blank in Django

Tag Kemar Joint