Prettier with ESLint

Prettier is (as it says on their website) am opiniated code formatter.

To begin with I’m going to extend the code from the last post ESLint with airbnb rules. Carry out the following steps

  • yarn add prettier -D
  • yarn add eslint-config-prettier -D

    This line will disable rules that conflict with Prettier

  • yarn add eslint-plugin-prettier -D>
  • Open .eslintc.js and update/add the following value to each key
    plugins: ['prettier']
    extends: [
    rules:  {
       'prettier/prettier': 'error'
  • Run yarn lint which we added in the ESLint with airbnb rules post.

The first thing you might notice, as I did, that the ESLint rules required a single quote for strings whereas Prettier requires double quotes, obviously this is not too good if you started running this tool against existing projects, so we want a way to disable such rules in Prettier.

Create a file named .prettierrc.js and place the following code in it

module.exports = {
    singleQuote: true

See Prettier configuration for more info.

ESLint with airbnb rules

I’ve covered using lint with TypeScript in my post Using ESLint on TypeScript files.

In this post I’m going to configure up a React application and set-up the project to use Airbnb’s ruleset for ESLint. The Airbnb ruleset appears (but I may be wrong) to be one of the most complete sets and appears to be a bit of a standard for devs.

So let’s create an application and install all the packages we need

  • yarn create react-app your-app-name –typescript
  • yarn add eslint -D
  • yarn add eslint-config-Airbnb -D
  • yarn add eslint-plugin-import -D
  • yarn add eslint-plugin-jsx-a11y -D
  • yarn add eslint-plugin-react -D
  • Add the following to the package.json file, scripts section
    "lint": "eslint --ext .js,.jsx,.ts,.tsx ."
  • Add file .eslintignore to the root folder with the following
  • Add the file .eslintrc.js to the root foldr also, with the following
    module.exports =  {
        parser:  '@typescript-eslint/parser',  // Specifies the ESLint parser
        plugins: ['@typescript-eslint'],
        extends:  [
          'plugin:react/recommended',  // Uses the recommended rules from @eslint-plugin-react
          'plugin:@typescript-eslint/recommended',  // Uses the recommended rules from @typescript-eslint/eslint-plugin
        parserOptions:  {
            ecmaVersion:  2018,  // Allows for the parsing of modern ECMAScript features
            sourceType:  'module',  // Allows for the use of imports
            ecmaFeatures:  {
            jsx:  true,  // Allows for the parsing of JSX
        rules:  {
        settings:  {
          react:  {
            version:  'detect',  // Tells eslint-plugin-react to automatically detect the version of React to use

If all worked, you can no run yarn lint and should see (probably) a fair few errors and warnings. We haven’t even added our own code yet!

Let’s clean a couple of things up first. The serviceWorker.ts file is generated via the React scaffolding, so me might simply want to add the filename to the .eslintignore file, that file looks like this now


This will greatly reduce the errors/warnings. After re-running lint I have two errors and a warning within the file App.test.tsx, one of which suggest function it (the aliased test function) is not defined.

We have choices here, we can switch the rule to a warning or turn it off, we can add the file to the .eslintignore or we can add a comment block to the top of the file like this

/* eslint-disable */

Now, running lint will ignore this file.

In fact we could using the above with the following to disable a block of code from lint

/* eslint-enable */

We could also disable specific rules across a file/block using

/* eslint no-undef: "off" */

Next up I have index.tsx with an error, ‘document is not defined’. In this case I do not wish to ignore the whole file so we can ignore the specific line of code by placing this comment on the line above the document usage

// eslint-disable-next-line

This is fine but is fairly coarse in that it will ignore any other issues on that line, so we might prefer to disable the next line specific rule, i.e.

// eslint-disable-next-line no-undef

After these changes I ran lint again and had yet more errors and warnings, now in App.tsx. In my case lint states 1 error may be potentially fixable with the –fix option, so let’s see by running yarn lint –fix and then I fix the remaining errors and warnings myself.

At this point you may have had at least one error or warning which you consider to be too strict. The Airbnb rules are quite extensive and therefor quite strict. If you’re wanting to change the rule’s severity or turn the rule off, just go to the .eslintrc.js file and change the code specific to the rule that you want to edit. For example, if you’re coming from C# you might prefix your interfaces with I, by default this is classed as an error – let’s the rule off using

rules:  {
   '@typescript-eslint/interface-name-prefix': 'off'

or maybe you would prefer your project moves away from the I prefix but don’t want this to cause an error, then we can change ‘off’ to ‘warn’. So the three states we can set rules to are ‘off’, ‘warn’ and ‘error’.


Airbnb JavaScript Style Guide
ESLint Rules

React pure component

I’m using the Airbnb style guide with eslint and one warning mentioned that a very simple Component subclass with no properties or state but it just has a render method, should probably be written as a pure component.

Below is an example of a pure component in it’s most simplistic and minimal form.

import React, { ReactElement } from 'react';

const MyButton = (): ReactElement => (
  <div>My Button</div>

export default MyButton;

React also comes with a PureComponent base class, hence we could write

class MyButton extends React.PureComponent {
   render() {
      <div>My Button</div>

This is slightly different to our function version of a pure component in that it also handles properties and state, see the documentation for more information.

In both cases, these changes from a standard React Component result in performance increases, so very much worth baring in mind if your components are able to be written in these ways.

Getting started with Redux in React

Lot’s of Getting started posts at the moment, and probably a lot more to come. This one’s on using Redux with React and TypeScript.

Let’s create a sample application…

  • yarn create react-app {insert app name} –typescript
  • yarn add redux
  • yarn add react-redux
  • yarn add @types/react-redux
  • We can now delete the App.* files and the *.svg
  • Add folder components to src and also reducers
  • In src/components add Counter.tsx (we’re going to recreate the redux example component for in a tsx). Here’s the code
    import React, { Component } from 'react';
    interface CounterProps {
        value: number;
        onIncrement: () => void;
        onDecrement: () => void;
    export default class Counter extends Component<CounterProps, {}> {
        constructor(props: CounterProps) {
            this.incrementAsync = this.incrementAsync.bind(this);
            this.incrementIfOdd = this.incrementIfOdd.bind(this);
        incrementIfOdd() {
            if (this.props.value % 2 !== 0) {
        incrementAsync() {
          setTimeout(this.props.onIncrement, 1000)
        render() {
            const { value, onIncrement, onDecrement } = this.props
            return (
                Clicked: {value} times
                {' '}
                <button onClick={onIncrement}>
                {' '}
                <button onClick={onDecrement}>
                {' '}
                <button onClick={this.incrementIfOdd}>
                  Increment if odd
                {' '}
                <button onClick={this.incrementAsync}>
                  Increment async
  • Now in src/reducers add the file counterReducer.ts and put the following code into it
    export default (state: number = 0, action: any) => {
        switch (action.type) {
          case 'INCREMENT':
            return state + 1
          case 'DECREMENT':
            return state - 1
            return state
  • Finally, replace the contents of the index.tsx with the following
    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import * as serviceWorker from './serviceWorker';
    import { Provider } from 'react-redux'
    import { createStore } from 'redux'
    import counter from './reducers';
    import Counter from './components/Counter';
    const store = createStore(counter);
    const render = () => {
            <Provider store={store}>
                    value={store.getState() as number}
                    onIncrement={() => store.dispatch({ type: 'INCREMENT' })}
                    onDecrement={() => store.dispatch({ type: 'DECREMENT' })}
  • If everything is correct you should be able to execute yarn start and see the web page with +, – buttons etc. and clicking + or – will increment and decrement the displayed counter.

That’s a lot to take in, so what have we actually done?

Redux supplied a storage container for our application state. In the index.tsx file we create a store passing our reducer (src/reducers/counterReducer.ts) Reducers are called in response to the store.dispatch calls. In this case within index.tsx we dispatch the actions with the type set to strings INCREMENT and DECREMENT. The reducer receives these messages then makes state changes (although not actually changing the state directly but returning a new state).

As the Redux documentation on reducers states, “Remember that actions only describe what happened, but don’t describe how the application’s state changes”.

The next piece of code to look at is


We’ve wrapped the render code for the application in the render function. Subscribe then allows us to listen to messages on the redux store and calls the render function to render changes. The following part of the Counter code within the index.tsx file then simply assigns the current store state to the Counter value property

value={store.getState() as number

There’s not lot to really say about the Counter component which is standard React code for displaying buttons etc. and exposing properties as used in index.tsx.


This is a simplistic example. Redux documentation states that it’s not advisable to write the store.subscribe code but instead use the connect function provided by React Redux for this functionality.

In this instance we create a src/containers folder and add the file CounterContainer.ts, here’s the code

import {  connect } from 'react-redux'
import Counter from './../components/Counter';

const mapStateToProps = (state: any) => {
    return {
        value: state as number

const mapDispatchToProps = (dispatch: any) => {
    return {
        onIncrement: () => dispatch({ type: 'INCREMENT' }),
        onDecrement: () => dispatch({ type: 'DECREMENT' }),

export const CounterLink = connect(

export default CounterLink;

Here we write code to map state to properties and dispatch to properties (if we don’t handle either of these we simply supply a null in place of the function in the connect function.

As you can probably see, in mapStateToProps, the state is supplied and we simply apply it to the value property (which is on our Counter). In mapDispatchToProps we link the onIncrement and onDecrement to the dispatch functions.

Finally in index.tsx replace the Counter component with our newly created and exported CounterLink, i.e. here the new index.tsx

import React from 'react';
import ReactDOM from 'react-dom';
import * as serviceWorker from './serviceWorker';
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import counterReducer from './reducers/counterReducer';
import CounterLink from './containers/CounterContainer';

const store = createStore(counterReducer);

    <Provider store={store}>
        <CounterLink />


TypeScript’s never type, what’s the point ?

At first the never type may seem a slightly odd, possibly even pointless type. It can be used to denote that a function never returns, such as an infinite loop or a function simply throws an Error, hence again, never returns. These use cases don’t seem that useful, but you get the idea. The never type denotes that something should never occur.

Where never becomes a lot more useful is in situations where something should never occur in your application’s control flow, specifically regarding choice operators such as switch statements and if..else when used for exhaustive checks.

Let’s look at an example of this…

You have an type Choice which is currently made up of a union of three values, which looks like this

type Choice = 'A' | 'B' | 'C';

Let’s now create a simple function which returns a string based upon the choice value

function makeChoice(choice: Choice) {
  switch(choice) {
    case 'A': return 'A selected'
    case 'B': return 'B selected'
    case 'C': return 'C selected'
  // should never reach


We’re handling all the possible values of the union and all is fine with the world.

TypeScript correctly transpiles the code and if we mistakenly replace the change makeChoice(‘C’) to makeChoice(‘D’) (not included in the union) TypeScript reports the error Argument of type ‘”D”‘ is not assignable to parameter of type ‘Choice’.

What happens is – if we had a default case or if the options within the switch were exhausted and the instruction pointer made it to the comment part of the function – which in this case should never occur (as all values in the union are handled). This is where the never type comes in once all options are exhausted the choice variable in essence becomes a type never. I know, it seems strange, but read on…

So, what if we add a new value to the Choice union, let’s say ‘D’, then we have a bit of a problem, TypeScript will transpile without error but our case statement is not handling the new value and hence this may get into production without warning.

Let’s make this a little more obvious by changing our code to this

function makeChoice(choice: Choice) {
  switch(choice) {
    case 'A': return 'A selected'
    case 'B': return 'B selected'
    case 'C': return 'C selected'
  let c: never = choice;

Note: Assuming unused variables are not set as errors in your preferred linter then everything will compile and appear without error.

What’s happening here is that the transpiler knows that all choice options are exhausted, hence choice (if you like) changes to become of type never. Hence the line of code let c: never = choice; is valid as this line/instruction should never occur.

What happens it we add a new choice, so we now add ‘D’ to the Choice union and TypeScript will now report an error. This is because the choice variable may now have another value which is not handled by the switch statement and we’ll get the following error “Type ‘”D”‘ is not assignable to type ‘never'”. Which is good because now when we transpile time we’ll be alerted to a potential issue.

Prior to adding the let c: never = choice if we transpile the code to JavaScript we get the following code, which if we change ‘C’ to ‘D’ will not report any problem (which could be fine or could be bad depending upon our usage).

function makeChoice(choice) {
   switch (choice) {
      case 'A': return 'A selected';
      case 'B': return 'B selected';
      case 'C': return 'C selected';

So what we really want to do in our TypeScript file is throw an Error in place of the let c: never = choice, then this will catch non-exhaustive switch statements and will be transpiled into JavaScript to give us a runtime guard to highlight a potential issue.

Let’s create a simple function to handle this so our code now looks like this

function unreachable(param: never): never { 
   throw new Error('should not reach here')

function makeChoice(choice: Choice) {
  switch(choice) {
    case 'A': return 'A selected'
    case 'B': return 'B selected'
    case 'C': return 'C selected'

which transpiles to almost exactly the same code.

As the function unreachable never returns, we mark it as such by using the never return type.

If we now try to pass ‘D’ to the function makeChoice in the JavaScript code, an exception will occur so we’re covered at runtime now as well as at tranpsile time.

Another example of using never is in the type NonNullable which is part of TypeScript.

type NonNullable<T> = T extends null | undefined ? never : T;

In this instance if the generic type T is null or undefined then never is returned, hence the following type will actually be of type never and this not assignable to

type A = NonNullable<null>;

Getting started with Storybook

Storybook allows us to prototype and test UI components in isolation from your application. We’re going to “get started” using Storybook with React, but it also supports Vue and Angular.

Let’s create the project and add required libraries.

Note, that the npx command should not be run from VSCode (or other Atom based editor by the sounds of it), I got an error EPERM: operation not permitted, unlink.

In the steps below we also install enzyme for test rendering. We’ll also add material-ui, just for the fun of it.

  • npx -p @storybook/cli sb init
  • yarn create react-app storybooksample –typescript
  • yarn add @types/storybook__react -D
  • yarn add @types/enzyme -D
  • yarn add enzyme -D
  • yarn add enzyme-adapter-react-16 -D
  • yarn add @types/enzyme-adapter-react-16 -D
  • yarn add @material-ui/core

The storybook “getting started” web page suggests we now run the following commands to check everything was installed correctly, so let’s do this, run

  • yarn test
  • yarn storybook

Let’s now remove the storybook generated code as we’ll replace this with our own code. So in the folder src/stories, delete index.js and add a file named setupTests.ts to the src folder, here’s the code for this file

import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

configure({ adapter: new Adapter() });

Before we go too much further let’s create a sample component that will use to demonstrate testing via storybook. In the src folder add a folder named components/LogButton and in this create a file named LogButton.tsx – the name’s unimportant ofcourse, this is just a sample component which will be a new Button component, but hopefully will help demonstrate how we can use storybook.

In LogButton.tsx place the following code

import React from 'react';
import Button from '@material-ui/core/Button';

interface LogButtonProps {
    onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;

export class LogButton extends React.Component<LogButtonProps, {}>{    
   render() {
      return (
            <Button variant='contained' onClick={this.props.onClick}>Log</Button>

Let’s now create a standard unit test for this component, this is not required for storyboard, but it’s good practise. In the same src/components/LogButton folder add the file LogButton.test.tsx and here’s a very simple test to got into this file

import React from 'react';
import { mount } from "enzyme";
import { LogButton } from "./LogButton";

test('Loading component should not throw error', () => {
    const logButton = mount(<LogButton />);

This will just check that the component, when loaded, loads successfully. We can now run yarn test to verify this code works.

Now let’s get storybook up and running with our component.

In the .storybook folder, replace the config.js code with the following

import { configure } from '@storybook/react';

const req = require.context('../src', true, /.stories.(ts|tsx|js)$/)
const loadStories = () => req.keys().forEach(filename => req(filename));
configure(loadStories, module)

This will automatically load stories based upon the filename/extensions .stories.

Alongside LogButton.tsx and LogButton.test.tsx, add LogButton.stories.tsx. This will supply the code required to integrate into storybook and also allow us to write code to allow us to test the UI component via storybook.

import React from 'react';
import { storiesOf } from '@storybook/react';
import { LogButton } from './LogButton';
import { action } from '@storybook/addon-actions';

storiesOf('LogButton', module)
    .add("Log", () => <LogButton onClick={action('clicked')} />);

Now run yarn storybook and the storybook server and UI should display along with our LogButton now being the only component available. Selecting the “Log” story, when the LogButton is clicked the action will display the text “clicked”.

So what we’ve done is create a very simply component based upon a Button which we also declared some properties – well in this case we’ve created a single property, an onClick event. The story created for the button then hooks into the button’s click event and when used via storybook allows us to test the control in isolation via storybook’s UI. This is not a unit test or automated test so much as an interactive UI test where, as developers, we can verify our functionality. Let’s say the Button’s text changed when clicked, now we could start interacting with the button via storybook and confirm everything works as expected.

There’s a lot more to storyboard than the above, but this is a good starting point.

Creating React components in TypeScript

By default we’ll usually create a React component (in a .tsx file) using a React.Component base class, for example

export default class GridSampleComponent extends Component<{}, {}> {
   render() {
      return (

But as per my post here we can also create components through functions, which ofcourse makes sense when you see a .jsx file which tend to default to using functions.

Hence we can create the following

const MyButton = (props: any) => {
      <Button variant="contained" 

In the code above we’ve basically created a new component from the function which takes properties which are implicitly passed to the function via React, i.e. the code for using the above might look like this


The child elements are passed through to our function. In this case it’s just the string “Hello”.

Yarn and what not to commit to your source repos

When working with yarn you’ll find your source code folder includes the following files and folder (amongst others)

  • packages.json
  • yarn.lock
  • node_modules

If using TypeScript you may also have tsconfig.json.

The node_modules folder is basically everything downloaded via yarn that are either included within the packages.json or dependencies of those packages. So unless you’re fearful of versions of mdoules/dependencies becoming unavailable, this folder can be left out of source control, plus it can get big quickly.

The packages.json file should be committed as it obviously includes all the information regarding the packages used and their versions, but is also used for scripts etc.

Interestingly, I thought that yarn.lock should also be excluded as it’s generated by yarn, but according to Lockfiles should be committed on all projects.

If you have tsconfig.json, this file is a TypeScript configuration file. Hence this should be committed to ensure other team members are using the same configuration.

What about .vscode

If you’re using VSCode as your editor/development tool then you’ll notice that a .vscode folder is created in some cases with settings.json etc. within it.

Obviously whether you commit .vscode (or individual files within it) depends on whether you’re also aiming to commit shared settings etc. To my mind this would be a good thing as I use multiple machines for development and it’s an easy way for me to share settings between machines. This said if you’re a larger team it also might be useful to ensure everyone uses the same settings.

Using the Windows Subsystem for Linux

Whilst I have Linux machines available to me, they’re not always powered up or the remoting

See Windows Subsystem for Linux Installation Guide for Windows 10 for details on installing the WSL.

For completeness here’s the steps I took.

  • Run PowerShell as Admin and then execute the following

    Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
  • Go to the Microsoft Store and type Run Linux on Windows into the search text box. In the store currently, there’s the options of Ubuntu, openSUSE Leap 42, SUSE Linux Enterprise Server 12, Debian and Kali Linux.

    Install your preferred distro – I went for Ubuntu simply because that’s what I have on most of my Linux boxes.

  • Once installed you’ll need to go to the command prompt | Properties and select the Options tab. From here ensure that Use legacy console (requires relaunch) is unchecked.

Once everything is initialized you’ll be in the user’s (whatever user name you created) home folder – on Windows this folder is stored in C:\Users\{username}\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\rootfs\home

We can access the C drive using

cd /mnt/c

Running the Linux from Windows

When you want to run the Windows Subsystem for Linux going forward, simply execute


Typescript interfaces

Interfaces (within Typescript) are used in a variety of ways.

Defining expectations/restrictions

We can define an interface such as IPoint

interface IPoint {
    x: number;
    y: number;

Just like other languages, we can then implement this interface and we’re required to duplicate the properties or methods declared on it.

For example here’s an implementation

class Point implements IPoint {
    constructor(public x: number, public y: number) {        

We’ve used public constructor parameters hence implementing the IPoint interface.

Now we can create an instance of the Point like this

// p is a Point
var p = new Point(2, 3);
// p is declared as an IPoint
var p: IPoint = new Point(2, 3);

Within TypeScript an interface can also simply be thought of as shaping our data, so in this example we could create an anonymous class of type IPoint like this

var p: IPoint = {x : 2, y: 4};

We can also declare an instance of an anonymous type like this

var p = {x : 2, y: 4};

Typescript supports “duck typing” so we can create functions such as

function output(p: IPoint) {

and we can pass a type which implements an IPoint or a duck typed anonymous type, for example

output({x : 2, y: 4});

Because of duck typing we do have an issue whereby the following two interfaces are structurally equivalent

interface IPoint {
    x: number;
    y: number;

interface I2d {
    x: number;
    y: number;

and hence this will compile and run

var i2d: I2d = {x : 2, y: 4};
var p: IPoint = i2d;

In such a case, the interfaces have the same properties and names and are structurally equivalent.

Things get a little more interesting with interfaces and anonymous types, in that we can write something like this

function whatIsThis() {
    return {x:2};

Obviously it’s not an IPoint or I2d, but it could be. In this example it’d create an anonymous type but we could cast the type like this, but this will fail to compile due to the missing y property.

function whatIsThis() {
    return <IPoint>{x:2};

Empty interfaces

We can also define empty interfaces, such as

interface IEmpty {}

function output(e: IEmpty) {

output("Hello World");

In this case this is equivalent to an any and hence does not cause a compile time error and output will display “Hello World”.

Type erasure

Interfaces within Typescript are erased at compile/transpile time, hence whilst they aid in ensuring our types are as expected, once compiled to JavaScript they’re removed.

Hence no runtime type checking exists for such types.