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!

Leave a Reply for charlee Cancel Reply

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

  • synthroid 0.025 June 20, 2019

    synthroid 0.025

    synthroid 0.025

  • robaxin dosage for muscle spasm June 20, 2019

    robaxin dosage for muscle spasm

    robaxin dosage for muscle spasm

  • diltiazem gtt June 20, 2019

    diltiazem gtt

    diltiazem gtt

  • protonix dose June 20, 2019

    protonix dose

    protonix dose

  • wellbutrin and effexor June 20, 2019

    wellbutrin and effexor

    wellbutrin and effexor

  • celecoxib over the counter June 20, 2019

    celecoxib over the counter

    celecoxib over the counter

  • celexa side effects in females June 20, 2019

    celexa side effects in females

    celexa side effects in females

  • muscle relaxant baclofen June 20, 2019

    muscle relaxant baclofen

    muscle relaxant baclofen

  • amitriptyline brand June 20, 2019

    amitriptyline brand

    amitriptyline brand

  • aripiprazole 5mg tablets June 20, 2019

    aripiprazole 5mg tablets

    aripiprazole 5mg tablets

  • ddavp in siadh June 20, 2019

    ddavp in siadh

    ddavp in siadh

  • diclofenac sodium topical gel 1% June 20, 2019

    diclofenac sodium topical gel 1%

    diclofenac sodium topical gel 1%

  • can you drink alcohol on amoxicillin June 20, 2019

    can you drink alcohol on amoxicillin

    can you drink alcohol on amoxicillin

  • is bactrim a strong antibiotic June 20, 2019

    is bactrim a strong antibiotic

    is bactrim a strong antibiotic

  • ciprofloxacin expired 1 year ago June 20, 2019

    ciprofloxacin expired 1 year ago

    ciprofloxacin expired 1 year ago

  • where can you buy real viagra online June 20, 2019

    where can you buy real viagra online

    where can you buy real viagra online

  • are keflex and cefazolin in the same family June 20, 2019

    are keflex and cefazolin in the same family

    are keflex and cefazolin in the same family

  • can you take cymbalta and lexapro together June 20, 2019

    can you take cymbalta and lexapro together

    can you take cymbalta and lexapro together

  • rybelsus 14 mg June 20, 2019

    rybelsus 14 mg

    rybelsus 14 mg

  • rybelsus 3 mg coupon June 20, 2019

    rybelsus 3 mg coupon

    rybelsus 3 mg coupon

  • gabapentin act June 20, 2019

    gabapentin act

    gabapentin act

  • cialis buy online June 20, 2019

    cialis buy online

    cialis buy online

  • cialis blac June 20, 2019

    cialis blac

    cialis blac

  • viagra prescription usa June 20, 2019

    viagra prescription usa

    viagra prescription usa

  • cost of sildenafil in canada June 20, 2019

    cost of sildenafil in canada

    cost of sildenafil in canada

  • 200 mg generic viagra June 20, 2019

    200 mg generic viagra

    200 mg generic viagra

  • cialis over the counter 2018 June 20, 2019

    cialis over the counter 2018

    cialis over the counter 2018

  • rx warehouse pharmacy June 20, 2019

    rx warehouse pharmacy

    rx warehouse pharmacy

  • cialis canada org doc June 20, 2019

    cialis canada org doc

    cialis canada org doc

  • best valium pharmacy June 20, 2019

    best valium pharmacy

    best valium pharmacy

  • cialis walgreens June 20, 2019

    cialis walgreens

    cialis walgreens

  • can you buy real viagra online June 20, 2019

    can you buy real viagra online

    can you buy real viagra online

  • viagra 100 mg canada June 20, 2019

    viagra 100 mg canada

    viagra 100 mg canada

  • shelf life of cialis June 20, 2019

    shelf life of cialis

    shelf life of cialis

  • cialis generic online uk June 20, 2019

    cialis generic online uk

    cialis generic online uk

  • 20 mg generic sildenafil June 20, 2019

    20 mg generic sildenafil

    20 mg generic sildenafil

  • where to buy viagra in india June 20, 2019

    where to buy viagra in india

    where to buy viagra in india

  • cialis blood pressure June 20, 2019

    cialis blood pressure

    cialis blood pressure

  • best way to take cialis June 20, 2019

    best way to take cialis

    best way to take cialis

  • viagra 2010 June 20, 2019

    viagra 2010

    viagra 2010

  • cialis when to take June 20, 2019

    cialis when to take

    cialis when to take

  • buy valium from trusted pharmacy June 20, 2019

    buy valium from trusted pharmacy

    buy valium from trusted pharmacy

  • wedgewood pharmacy flagyl June 20, 2019

    wedgewood pharmacy flagyl

    Typing React (1) – Basic – Charlee Li

  • accutane pharmacy June 20, 2019

    accutane pharmacy

    Typing React (1) – Basic – Charlee Li

  • online pharmacy finpecia June 20, 2019

    online pharmacy finpecia

    Typing React (1) – Basic – Charlee Li

  • viagra verified internet pharmacy practice sites June 20, 2019

    viagra verified internet pharmacy practice sites

    Typing React (1) – Basic – Charlee Li

  • help me write a compare and contrast essay June 20, 2019

    help me write a compare and contrast essay

    Typing React (1) – Basic – Charlee Li

  • professional essay writer June 20, 2019

    professional essay writer

    Typing React (1) – Basic – Charlee Li

  • essay writting service June 20, 2019

    essay writting service

    Typing React (1) – Basic – Charlee Li

  • best essay cheap June 20, 2019

    best essay cheap

    Typing React (1) – Basic – Charlee Li

  • need help writing an essay June 20, 2019

    need help writing an essay

    Typing React (1) – Basic – Charlee Li

  • help writing college essay June 20, 2019

    help writing college essay

    Typing React (1) – Basic – Charlee Li

  • help writing essays for scholarships June 20, 2019

    help writing essays for scholarships

    Typing React (1) – Basic – Charlee Li

  • essay help sydney June 20, 2019

    essay help sydney

    Typing React (1) – Basic – Charlee Li

  • custom essay writing services June 20, 2019

    custom essay writing services

    Typing React (1) – Basic – Charlee Li

  • help me with my essay June 20, 2019

    help me with my essay

    Typing React (1) – Basic – Charlee Li

  • college application essay help online June 20, 2019

    college application essay help online

    Typing React (1) – Basic – Charlee Li

  • best custom essay site June 20, 2019

    best custom essay site

    Typing React (1) – Basic – Charlee Li

  • sat essay writing help June 20, 2019

    sat essay writing help

    Typing React (1) – Basic – Charlee Li

  • essay writing service recommendation June 20, 2019

    essay writing service recommendation

    Typing React (1) – Basic – Charlee Li

  • mba essay writing service June 20, 2019

    mba essay writing service

    Typing React (1) – Basic – Charlee Li

  • sildenafil pills buy June 20, 2019

    sildenafil pills buy

    Typing React (1) – Basic – Charlee Li