Migrate Angular 8 from TSLint to ESLint

Babette Landmesser
Oct 2, 2019 · 5 min read

At the end of 2019, TSLint — which is shipped with Angular core — will be deprecated. In advance, I switched from TSLint to ESLint to make migration easier and without being dependent on Angular releases.

Image for post
Image for post

In my daily routine as a frontend and Angular developer, I am confronted with code linting in TypeScript all the time. The Angular framework works with TypeScript and therefore added the TSLint package from palantir as a dependency. Also, Angular ships with basic TypeScript linting and serves CLI commands for checking code styles.

Sadly, palantir announced in February 2019 that the support for TSLint will be stopped at the end of the year. As a developer heavily relying on the linting and code style checks, I asked myself how to continue.

Unfortunately, Angular does not really seem to care about this. Issues for comments on the change were raised by users but not answered properly. It still seems that Angular has no real plan for migrating to ESLint — although they plan to release Angular 9 in fall 2019.

Additionally it’s quite difficult to find any help or existing articles.

Nevertheless, I feel it’s important to be prepared for unsupported TSLint so I started the migration for my Angular app on my own. In the following I will show you what I did, which conflicts I was confronted with and how I finally made ESLint work for TypeScript in an Angular environment.

Install dependencies

First of all, install the basic packages for eslint and typescript-eslint.

WARNING: I am using eslint 5.16.0 and tslint 5.18.0. With the newer version of eslint, I didn’t get the app working so far because the use of ecmaVersion has changed during this update.

@typescript-eslint is a package for extending the usual ESLint with TypeScript features, mainly of course variable types.
And also, TypeScript is parsed in a different way than ECMAScript, we also need a special parser for our linting.
In addition, @typescript-eslint/eslint-plugin adds some very specific TypeScript rules to the set of recommended ES rules, such as checking for setting the types to variables.

Basic configuration

In the next step — be aware to have tslint 5.18.0, otherwise this step is not possible — I used a package to convert my TSLint file automatically to a best possible ESLint file:

This script created a basic .eslintrc.js file with the rules it automatically detected from TSLint. As assumed, it didn’t match the complete set of TSLint rules. The reason for this is mainly the difference of the abstract syntax tree (AST) which is very different. But I won’t go into that. You can read more about AST in JavaScript here or here on TypeScript.
The basic structure of my generated eslint.js file looks like this

So the plugin already detected how TSLint was configured and added the parser and its options, it added the environments and of course the needed plugin for TypeScript with ESLint. In the rules object, it added the rules which it automatically detected and for which the tool was able to “translate” it into ESLint or the TypeScript plugin. In addition, it pasted all rules from previous TSLint file. You can compare the TSLint and the first draft of ESLint files here:
ESLint after first generation, previous TSLint.

The most important part of the ESLint configuration in a previous TSLint project is the parser. As I mentioned before, TypeScript has a different AST than ECMAScript. ESLint obviously ships with an ES parser and we need to add our custom TypeScript parser. The use of the config plugin cared about this step already. It also preconfigured the linter to check on the already existing tsconfig.json. Most important, it added the sourceType “module” to the parserOption which defines the code to be written in ECMAScript modules instead of default script syntax.

In “env” we are able to define global variables which come with predefined parts, such as browser (uses global browser variables) or common node variables. There’s a list of further environments to be added.

Executing ESLint

As a next step, I prepared my package.json file to add an ESLint command in “scripts” section.

Now I was able to run

and saw the shocking results. I got a ton of errors. The most common error I got is “ImportDeclaration should appear when the mode is ES6 and in the module context”. Ok, I was pretty stuck. I had no idea what this means. I didn’t want my code to be checked on ES6 because I need to support for example IE 11 and I need the target to be ES5. Secondly, my current setup seems to be fine too, I didn’t see why I should add an ImportDeclaration everytime.

So I started my research on this topic and I found the magic of parserOption “ecmaVersion”. If the sourceType is set to “module”, it automatically expected an ecmaVersion of 2015 or ES6. So I had to set it to 5 explicitly.

Image for post
Image for post
Values for ecmaVersion “translated” from tsconfig.json

After that nearly all errors were gone.

Final adjustments

I can now start adding my own rules but this would be a lot of work. Not mentioning the maintenance of these rules. I decided to use ESLint with extending “@typescript-eslint/eslint-recommended” and “@typescript-eslint/recommended”. Again, I got a lot of errors, for example the use of “any” as a type was not allowed.

Now I was able to start adding my custom rules. ESLint allows three values for rules. “Off” or 0 for a rule that doesn’t need to match, “warn” or 1 for a rule that should match but is not a requirement and “error” or 2 for a rule that has to be applied. Pretty easy.

Checking my TSLint file and searching for matching ESLint or typescript-eslint rules, I added a set of rules to match. You find the final eslint file here.

Finally my ESLint checks on rules I want to apply and I have to improve some lines of code but all in all I am pretty set up for a future without TSLint.

One last word though: An additional check for applying Angular specific TypeScript rules for checking Components and Pipes are not yet applied.

Create & Code


Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store