A good static analysis pipeline can be very helpful. Linting is among the most common and helpful types of static analysis for JavaScript. It can help catch bugs, enforce uniform code style, and prevent overly complex code.

If you have used JavaScript linting tools, you might be familiar with libraries such as JSLint, JSHint, or ESLint. The most popular TypeScript linting library is TSLint. It’s pretty similar to the well-known JavaScript linting libraries. In this post, I’ll describe how to install and configure it.

Installation and Setup

Installing TSLint is simple. Instructions can be found here. After installing, you can run

tslint --init

to generate a basic configuration file, which creates a tslint.json file that looks like this:

{ "extends": [ "tslint:recommended" ], "jsRules": {}, "rules": {}, "rulesDirectory": [] }

This configuration file can be provided when running TSLint. For example, the docs suggest the following to lint all of your TypeScript files:

tslint -c tslint.json 'src/**/*.ts'

If you are working on a React app, you probably want to include a tsx file as well, so you can update the file matcher to src/**/*.ts* .

I’m currently working on a full-stack TypeScript app using React. We have yarn scripts to lint our server app, client app, and both. Our package.json file contains the following lint tasks:

lint:client: "tslint -c ./tslint.json './client/**/*.ts*'" lint:server: "tslint -c ./tslint.json './server/**/*.ts'" lint: "yarn lint:client yarn && lint:server"

Configuration

Once you have TSLint installed and running, it’s important to make sure you have the right rules configured. The above default tslint.json just extends the recommended rule set tslint:recommended . No custom rules are set up by default.

The TSLint docs describe the recommended rule set as a

stable, somewhat opinionated set of rules which we encourage for general TypeScript programming

There are other base rule sets you can use. You can also manually enable or override rules.

As an example, the recommended rule set requires strings to be double quoted. This is controlled via the quotemark rule. If you’d prefer to use single quote marks, you can override that requirement by adding the following to the rules sections of your tslint.json file:

rules: { "quotemark": [true, "single"] }

A full set of rules and their descriptions can be found on the TSLint rules page.

TSLint-ESLint Rules

When working on our TSLint setup, I noticed that it didn’t support several rules that I wanted to use. For example, there isn’t a TSLint rule that enforces a standard indentation amount. The TSLint indent rule allows you to specify the type of indentation (tabs vs. spaces), but not the amount.

To solve this problem, I ended up using the TSLint-ESLint package. TSLint-ESLint supports most of the standard JavaScript ESLint rules and allows you to use them for your TypeScript code. After you install it, you can conveniently include it as a base rule set. This makes it really easy to integrate with TSLint.

For example, you can integrate TSLint-ESLint and set up a linting rule for two-space indentation via:

{ "extends": [ "tslint:recommended", "tslint-eslint-rules" ], "rules": { "ter-indent": [true, 2] } }

TSLint-ESLint provides a nice table of rules on its GitHub page. Each rule is categorized into one of four categories:

Sometimes, the JavaScript ESLint rules don’t make sense for TypeScript, and sometimes, they are already provided by TSLint. Occasionally, an ESLint rule is renamed because TSLint already defines a different rule with the same name.

This was the case for the indent example I mentioned above. TSLint had already defined a rule called indent that worked differently than the ESLint indent rule, so the TSLint-ESLint rule is named ter-indent instead.

More Base Rules

There are other base rule sets that are easy to integrate. tslint-react and tslint-immutable look especially interesting, though I have not tried them yet.

If anyone has had success with other base rule sets, or has a different linting setup that they really like, I would love to hear about it.