eslint: using overrides and file types

2021-01-04

 | 

~3 min read

 | 

439 words

When I wrote about using ESLint with Typescript previously, I assumed that the entire project would be using Typescript. There are plenty of reasons why this might not be the case. For example, some projects start as vanilla Javascript and migrate over time.

It’s this latter situation which I want to discuss today by looking at ESLint’s overrides functionality.

Take the basic eslintrc I used when describing the anatomy of ESLint’s configuration:

{
  "parserOptions": {
    "ecmaVersion": 10,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  },
  "extends": ["eslint:recommended", "eslint-config-prettier"],
  "rules": {
    "strict": ["error", "never"]
  },
  "env": {
    "browser": true
  },
}

In that original article, I noted that we would be skipping the parser option. That’s no longer an option. ESLint does not know how to parse Typescript files by default (it only processes .js files by default).

Updating The .eslintrc

To address this shortcoming, we can update our .eslintrc with a new object in the overrides.

{
  "parserOptions": {
    "ecmaVersion": 10,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  },
  "extends": ["eslint:recommended", "eslint-config-prettier"],
  "rules": {
    "strict": ["error", "never"]
  },
  "env": {
    "browser": true
  },
  //highlight-start
  "overrides": [
    {
      "files": "**/*.+(ts|tsx)",
      "parser": "@typescript-eslint/parser",
      "parserOptions": {
        "project": "./tsconfig.json"
      },
      "plugins": ["@typescript-eslint/eslint-plugin"],
      "extends": [
        "plugin:@typescript-eslint/eslint-recommended", // removes redundant warnings between TS & ESLint
        "plugin:@typescript-eslint/recommended", // rules specific to typescript, e.g., writing interfaces
        "eslint-config-prettier/@typescript-eslint" // ensure rule set doesn't conflict with prettier for TS files too
      ]
    }
  ]
  //highlight-end
}

The override tells ESLint what to do when it comes across a .ts or .tsx file.

First of all, we define a new parser @typescript-eslint/parser which has its own parser options API. In particular, it exposes a project variable which can point to a tsconfig.json and is required for using rules that rely on type information.

The plugins and extensions are then used to ensure that ESLint and Typescript don’t conflict or serve redundant error messages.

Using The New Configuration

Now that the configuration is updated, there are just a few more steps to tie it all together.

First, we need to install the parser and plugin.

$ npm install --save-dev @typescript-eslint/eslint-plugin @typescript-eslint/parser

Secondly, when running ESLint, we need to specify these additional file types, whether that’s directly from the command line or within a script in package.json:

package.json
{
    "scripts": {
        "lint": "eslint --ignore-path .gitignore --ext .js,.ts,.tsx ."
    }
}

Conclusion

Whether your entire project is written in Typescript or not, I found this exercise quite helpful in understanding on a deeper level how the ESLint can work with Typescript - particularly in defining the parser, parser options, and setting the plugins.


Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!