How to Lint All Files With Typescript ESLint
ESLint | Typescript
The Problem
Typescript ESLint is a great tool for adding linting to a Typescript project. It allows ESLint to natively parse Typescript syntax while also providing an extensive set of Typescript-specific rules. Many of these rules are “type-aware”, meaning they utilise the type information found within your project’s Typescript configuration (e.g., tsconfig.json
) to provide more powerful analysis.
However, when enabling these type-aware rules, you may start to encounter an issue where linting certain files results in an error, usually seen as:
Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: ...
The file must be included in at least one of the projects provided.
This is almost certainly because your ESLint configuration has been instructed to lint a file that does not belong to the Typescript project. Two common examples of this would be unit test files, or configuration files (such as .eslintrc.js
itself).
This article will look at an easy solution that avoids this problem and allows any files of your choosing to be linted. Similar advice is officially documented here, along with solutions that may be applicable in the scenario where you explicitly don’t want the problem files to be linted.
The Solution
We’ll demonstrate the solution by expanding upon one of the examples mentioned above. Let’s assume we have a project where we’ve enabled type-aware linting but still want our .eslintrc.js
file to be linted. We’d have a tsconfig.json
and an .eslintrc.js
that look something like the following (most options omitted for brevity):
// tsconfig.json
{
"compilerOptions": {
"outDir": "dist"
},
"include": ["src/**/*.ts"]
}
// .eslintrc.js
module.exports = {
parserOptions: {
parser: '@typescript-eslint/parser',
sourceType: 'module',
tsconfigRootDir: __dirname,
project: 'tsconfig.json',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
],
ignorePatterns: ['node_modules', 'dist'],
};
As you can see, our Typescript configuration instructs that the project should only include .ts
files within src
(does not include .eslintrc.js
), while our ESLint configuration has been instructed to lint everything outside of node_modules
and dist
(does include .eslintrc.js
). What happens when we try to run the linter? As you might have expected, we get the following error:
Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: .eslintrc.js.
The file must be included in at least one of the projects provided.
So, how do we fix this? We’ll simply create a separate Typescript configuration file and ask ESLint to use that instead. We’ll ensure the new configuration is derived from the original, so that we still provide the correct type information without repeating ourselves. Only this time, we’ll override the include
option to contain all the files we’re interested in linting.
Let’s see that in action. First, we’ll create a new tsconfig.eslint.json
file:
// tsconfig.eslint.json
{
"extends": "./tsconfig.json",
"include": ["./**/*.*"]
}
Notice how we use extends
to inherit from the base configuration, and use include
to now contain all files in the root directory (note that you may want to restrict this pattern if you find ./**/*.*
to be too broad).
Finally, we just have to update .eslintrc.js
and point it to our new ESLint-specific Typescript configuration:
// .eslintrc.js
module.exports = {
parserOptions: {
...,
project: 'tsconfig.eslint.json'
},
...
};
That’s it! Now when we run the linter, no errors should be thrown and .eslintrc.js
should be linted. Note how tsconfig.json
remains unchanged, and that the core Typescript project can continue to function as normal.