This blogpost was inspired by React Component Patterns post live Demo

If you know me, you already know that I don’t write javascript without types, so yeah I’m really into Typescript, since version 0.9. Beside typed JS I really love React, and when React + Typescript are combined, I just feel like in heaven :D. Full type safety within whole app and VDOM templates it’s just marvelous and joy to work with.

So what is this post all about? Well, there are various articles about React Component patterns on the internet, but none describes how to apply those patterns with Typescript. Also upcoming version of TS 2.8 brings new exciting features to the table, like conditional types, new predefined conditional types within standard library, homomorphic mapped types modifiers…, which allows us to create easily common react patterns in type safe way…

This post is gonna be quite long, so please just sit back and relax, while you master Ultimate React Component Patterns with Typescript!

all patterns/examples use typescript 2.8 and strict mode

Start

First off we need to install typescript and tslib helpers so our emitted code is smaller

yarn add -D typescript@next

# tslib will be leveraged only for features that are not natively supported by your compile target

yarn add tslib

With that we can initialize our typescript config:

# this will create tsconfig.json within our project with sane compiler defaults

yarn tsc --init

Now let’s install react, react-dom and their type definitions.

yarn add react react-dom

yarn add -D @types/{react,react-dom}

Great! Now let’s hop into those component patterns, shall we ?

Stateless Component

You guess it, those are components without state ( they are also called presentational ). Most of the time they are just pure functions. Let’s create contrived Button stateless compoennt with Typescript.

Like in vanilla JS we need to import React which allows us to use JSX

import React from 'react' const Button = ({ onClick: handleClick, children }) => (

<button onClick={handleClick}>{children}</button>

)

Although tsc compiler will now emit errors! We need to be explicit and tell the component/function what is the type of our props. Let’s define our props:

import React, { MouseEvent, ReactNode } from 'react'

type Props = {

onClick(e: MouseEvent<HTMLElement>): void

children?: ReactNode

} const Button = ({ onClick: handleClick, children }: Props) => (

<button onClick={handleClick}>{children}</button>

)

We get rid of all errors! great! But we can do even better!

There is a predefined type within @types/react => type SFC<P> which is just an alias of interface StatelessComponent<P> and it has pre-defined children and other things (defaultProps, displayName...), so we don't have to write it every time on our own!

So the final stateless component looks like this:

Stateless Component

Stateful Component

Let’s create stateful counter component which will leverage our Button

First of we need define initialState

const initialState = { clicksCount: 0 }

Now we will use Typescript to infer State type from our implementation.

By doing this we don’t have to maintain types and implementation separately, we have only source of truth, which is the implementation. nice !

type State = Readonly<typeof initialState>

Also note that type is explicitly mapped to have all properties read-only. We need to be explicit again and define use our State type to define state property on the class.

readonly state: State = initialState

Why is this useful/needed ? We know that we cannot update state directly within React like following:

this.state.clicksCount = 2

this.state = { clicksCount: 2 }

This will throw a runtime error, but not during compile time. By explicitly mapping our type State to readonly via Readonly and setting readonly state within our class component, TS will let us know that we are doing something wrong immediately.

Example:

Compile time State type safety

Whole Container/Stateful component implementation: