in Front End

Typing React (1) – Basic

TypeScript has been increasingly popular. The typing system helps eliminate most of the coding errors at compile time. Generally, TypeScript costs you a significant amount of time on coding and typing, but later on i will save you much more time on debugging.

This series attempts to facilitate the painful efforts of typing, especially when you are not quite familiar with TypeScript. Thus we will focus on typing and nothing else – anything not specifically related to TypeScript, such as the usage of redux, will be ignored.

The demo project for this series can be downloaded at my GitHub: https://github.com/charlee/todolist.

Create a Project

The popular create-react-app tool now supports creating application with TypeScript directly.

$ create-react-app todolist --typescript
$ cd todolist

Open the project folder and you will see index.tsx and App.tsx files. The naming convension is that files originally using JSX end with .tsx and pure TypeScript files end with .ts.

You may notice that TypeScript complains about the export of React has an implicit any type. This is because original React does not contain any typing definitions. Fix this by installing @types/react:

$ npm install --save @types/react

I would also recommend adding a .prettierrc.yaml in the project root directory with the following content. If you are using Visual Studio Code, you can press Cmd+Shift+F (Mac) or Ctrl+Shift+I (Windows/Linux) to auto format files:

printWidth: 90
tabWidth: 2
singleQuote: true
trailingComma: all

Component

It is also useful to define all the data models in one place, namely, src/models/types.d.ts:

declare module 'Models' {
  export interface Todo {
    id: number;
    text: string;
    done: boolean;
  };

  export type TodoList = Todo[];
}

When creating a component, you need to create an interface type for the props:

import React, { useState } from 'react';
import { Todo } from 'Models';

export interface IProps {
  todo: Todo;
}

const Todo: React.FC<Todo> = props => {
  const { todo } = props;
  const [expanded, setExpanded] = useState<boolean>(false);
  return <div>{todo.text}</div>;
};

export default Todo;

Or if you need to define old style components with classes, you can do this:

import React from 'react';
import { Todo } from 'Models';

export interface IProps {
  todo: Todo;
}

export interface IState {
  expanded: boolean;
}

class Todo extends React.Component<IProps, IState> {
  state: IState = {
    expanded: false,
  };

  render() {
    const { todo } = this.props;
    return <div>{todo.text}</div>;
  }
}

export default Todo;

Note that in the class definition, we need to define the type of the state property explicitly. This is because TypeScript cannot infer its type from the class (namely React.Component<IProps, IState>). Omitting the type like state = { expanded: false } works for this simple case, but if the state contains any typed list, TypeScript will complain that the empty list does not fit the type of the list:

// State type definition
export interface IState {
  todos: Todo[];
}

class TodoList extends React.Component<IProps, IState> {
  state = { todos: [] };  // WRONG: [] does not match Todo[]
}

Generic Component

One nice thing of TypeScript is generic. It allows us to extract the algorithm from the code. Similarly we can create generic component as well, to handle some common UI behaviors.

The following example shows a generic component called FilteredList. It accepts a list of objects in arbitrary type, a filter function, and filters the object list with the filter function, then pass the filtered list to its children.

import React from 'react';

export interface IProps<T> {
  objects: T[];
  filter: (o: T) => boolean;
  children: (objects: T[]) => JSX.Element;
}

const FilteredList = <T extends {}>(props: IProps<T>) => {
  const { children, objects, filter } = props;
  const filtered = objects.filter(o => filter(o));
  return <React.Fragment>{children(filtered)}</React.Fragment>;
};

export default FilteredList;

In above code we used a trick <T extends {}> instead of <T>. Although <T> is legal in TypeScript, it would be recognized as a tag in JSX and produce a compile error.

Note that although FilteredList is generic, in some case it can be used directly, given that TypeScript can infer its type parameter from its attributes:

export interface Todo {
  id: number;
  name: string;
}

export interface IProps {
  todos: Todo[];
}

const TodoList: React.FC<IProps> = props => {
  const { todos } = props;
  return (
    <FilteredList objects={todos} filter={o => o.name.startsWith('[URGENT]')}>
      {todos => (
        <React.Fragment>
          {todos.map(todo => (
            <TodoItem todo={todo} />
          ))}
        </React.Fragment>
      )}
    </FilteredList>
  );
};

Here we did not specify what T is when using <FilteredList>. It is completely inferred from its objects attribute.


That’s all for this post. I know I didn’t cover everything about typing, so you are welcome to comment anything you think worth to mention here. Thanks for reading!

Write a Comment

Comment

  1. Hello, thanks for article. After text `When creating a component, you need to create an interface type for the props:` you have mistake in React.FC. React.Fc is deprecated, use React.FuctionalComponent 🙂

Webmentions

  • World Market Link June 20, 2019

    … [Trackback]

    […] Find More to that Topic: charlee.li/typeing-react-1-basic/ […]

  • Mpo surga June 20, 2019

    … [Trackback]

    […] Info on that Topic: charlee.li/typeing-react-1-basic/ […]

  • white house market url June 20, 2019

    … [Trackback]

    […] Read More on that Topic: charlee.li/typeing-react-1-basic/ […]

  • Firearms For Sale June 20, 2019

    … [Trackback]

    […] Find More Info here to that Topic: charlee.li/typeing-react-1-basic/ […]

  • lenovo sunucu destek June 20, 2019

    … [Trackback]

    […] Read More on on that Topic: charlee.li/typeing-react-1-basic/ […]

  • Vice City Market Link June 20, 2019

    … [Trackback]

    […] Find More here on that Topic: charlee.li/typeing-react-1-basic/ […]

  • คา สิ โน ออนไลน์ ไม่มี ขั้น ต่ำ June 20, 2019

    … [Trackback]

    […] There you can find 21258 more Information to that Topic: charlee.li/typeing-react-1-basic/ […]

  • CHEE TING June 20, 2019

    … [Trackback]

    […] Find More Information here on that Topic: charlee.li/typeing-react-1-basic/ […]

  • Svenskt ID-kort June 20, 2019

    … [Trackback]

    […] Find More Info here on that Topic: charlee.li/typeing-react-1-basic/ […]

  • Supercritical CO2 Extraction Machine June 20, 2019

    … [Trackback]

    […] Read More on that Topic: charlee.li/typeing-react-1-basic/ […]

  • AD ASAN June 20, 2019

    … [Trackback]

    […] Read More on that Topic: charlee.li/typeing-react-1-basic/ […]

  • most expensive champagne bottle June 20, 2019

    … [Trackback]

    […] Info to that Topic: charlee.li/typeing-react-1-basic/ […]

  • HP Server Teknik Servis June 20, 2019

    … [Trackback]

    […] Find More Information here on that Topic: charlee.li/typeing-react-1-basic/ […]

  • world market link June 20, 2019

    … [Trackback]

    […] Read More Info here on that Topic: charlee.li/typeing-react-1-basic/ […]

  • HP Server Teknik Servis June 20, 2019

    … [Trackback]

    […] Find More here to that Topic: charlee.li/typeing-react-1-basic/ […]

  • Server Teknik Servis June 20, 2019

    … [Trackback]

    […] Read More here to that Topic: charlee.li/typeing-react-1-basic/ […]

  • dark0de market June 20, 2019

    … [Trackback]

    […] Info on that Topic: charlee.li/typeing-react-1-basic/ […]

  • Server Teknik Servis June 20, 2019

    … [Trackback]

    […] Information on that Topic: charlee.li/typeing-react-1-basic/ […]

  • kurumsal it danışmanlığı June 20, 2019

    … [Trackback]

    […] Info to that Topic: charlee.li/typeing-react-1-basic/ […]

  • microsoft exchange online plan 2 June 20, 2019

    … [Trackback]

    […] Find More Info here on that Topic: charlee.li/typeing-react-1-basic/ […]

  • HP Server Teknik Servis June 20, 2019

    … [Trackback]

    […] Read More to that Topic: charlee.li/typeing-react-1-basic/ […]

  • it danışmanlık sözleşmesi June 20, 2019

    … [Trackback]

    […] Read More here to that Topic: charlee.li/typeing-react-1-basic/ […]

  • dumps su June 20, 2019

    … [Trackback]

    […] Find More on on that Topic: charlee.li/typeing-react-1-basic/ […]

  • microsoft exchange June 20, 2019

    … [Trackback]

    […] There you will find 31833 additional Info on that Topic: charlee.li/typeing-react-1-basic/ […]

  • pkv games June 20, 2019

    … [Trackback]

    […] Find More on that Topic: charlee.li/typeing-react-1-basic/ […]

  • Facebook like count June 20, 2019

    Facebook like count

    grdwdsjqv qapio vjmgtcc iotd tdnqmrhqybefqwc