Skip to main content

Typed Linting

Editor ESLint reports become out-of-date after file changes

There is a known issue in at least VS Code with typed linting that files might have out-of-date lint errors after multiple updates to files on disk. The root cause is that ESLint doesn't provide a way for editors to know about cross-file dependencies, such as type information. This results in files receiving out-of-date type information when files they import from are changed.

You might see this as erroneous no-unsafe-* rule complaints on any or error typed values. Other rules may be more subtly incorrect.

For now, the workaround is to run the Restart ESLint Server command in VS Code (or an equivalent in other editors) when types get out of date.

See ESLint does not re-compute cross-file information on file changes (microsoft/vscode-eslint#1774) for more information.

How do I disable type-checked linting for a file?

Use ESLint's configuration objects with our disable-type-checked config to disable type checking for a files match that includes that file.

For example, to disable type-checked linting on all .js files:

eslint.config.mjs
import tseslint from 'typescript-eslint';

export default tseslint.config(
// ... the rest of your config ...
{
files: ['**/*.js'],
extends: [tseslint.configs.disableTypeChecked],
},
);

Alternatively to disable type checking for files manually, you can set parserOptions: { project: false } to an override for the files you wish to exclude.

typescript-eslint thinks my variable is never nullish / is any / etc., but that is clearly not the case to me

Our type-aware rules almost always trust the type information provided by the TypeScript compiler. Therefore, an easy way to check if our rule is behaving correctly is to inspect the type of the variable in question, such as by hovering over it in your IDE.

If the IDE also shows that the type is never nullish / is any, you need to fix the type. A very common case is with the no-unnecessary-condition rule. Take this code for example:

let condition = false;

const f = () => (condition = true);
f();

if (condition) {
//^^^^^^^^^ Unnecessary conditional, value is always falsy.
}

You can see that the type of condition is actually the literal type false by hovering over it in your IDE. In this case, typescript-eslint cannot possible know better than TypeScript itself, so you need to fix the report by fixing the type, such as through an assertion (let condition = false as boolean).

If the IDE provides different type information from typescript-eslint's report, then make sure that the TypeScript setup used for your IDE, typescript-eslint, and tsc are the same: the same TypeScript version, the same type-checking compiler options, and the same files being included in the project. For example, if a type is declared in another file but that file is not included, the type will become any, and cause our no-unsafe-* rules to report.

Are TypeScript project references supported?

Yes, but only with parserOptions.projectService.

See issue #2094 discussing project references for more details.

Project Service Issues

parserOptions.projectService is the recommended parser option to enable typed linting as of typescript-eslint v8. It enforces projects generate type information for typed linting from the same tsconfig.json files used by editors such as VS Code.

I get errors telling me "... was not found by the project service. Consider either including it in the tsconfig.json or including it in allowDefaultProject"

These errors are caused by attempting to use the project service to lint a file not explicitly included in its nearest tsconfig.json.

The project service will attempt to build type information for each file being linted using the nearest tsconfig.json on disk to that file. If that tsconfig.json does not include the file, and the file isn't allowlisted in allowDefaultProject, then the project service will throw this error.

For each file being reported:

Note also:

  • TSConfigs don't include .js files by default. Enabling allowJs or checkJs is required to do so.
  • The project service only looks at tsconfig.json files. It does not look at tsconfig.eslint.json or other coincidentally-similarly-named files.

If these steps don't work for you, please file an issue on typescript-eslint's typescript-estree package telling us your use case and why you need more out-of-project files linted. Be sure to include a minimal reproduction we can work with to understand your use case!

I get errors telling me "Having many files run with the default project is known to cause performance issues and slow down linting."

These errors are caused by attempting to use the project service to lint too many files not explicitly included in a tsconfig.json with its allowDefaultProject option.

typescript-eslint allows up to 8 "out of project" files by default. Each file causes a new TypeScript "program" to be built for each file it includes, which incurs a performance overhead for each file.

For each file being reported:

I'd like to use TSConfigs other than tsconfig.jsons for project service type information

Only the TSConfig path used for "out of project" files in allowDefaultProject can be customized. Otherwise, only tsconfig.json files on disk will be read.

For example, instead of:

  • tsconfig.jsons for building (and, coincidentally, type information in editors)
  • Separate TSConfig(s) like tsconfig.eslint.json for linting

Consider using:

  • tsconfig.jsons for linting (and, intentionally, the same type information in editors)
  • Separate TSConfig(s) like tsconfig.build.json for building

The project service uses the same underlying TypeScript logic as editors such as VS Code. Using only tsconfig.json for typed linting enforces that the types seen in your editor match what's used for linting.

Traditional Project Issues

I get errors telling me "ESLint was configured to run ... However, that TSConfig does not / none of those TSConfigs include this file"

These errors are caused by an ESLint config requesting type information be generated for a file that isn't included in the TypeScript configuration.

Fixing the Error

  • If you do not want to lint the file:
  • If you do want to lint the file:
    • If you do not want to lint the file with type-aware linting:
    • If you do want to lint the file with type-aware linting:
      • Check the include option of each of the TSConfigs that you provide to parserOptions.project - you must ensure that all files match an include glob, or else our tooling will not be able to find it.
        • If the file is a .cjs, .js, or .mjs file, make sure allowJs is enabled.
      • If your file shouldn't be a part of one of your existing tsconfigs (for example, it is a script/tool local to the repo), then consider creating a new tsconfig (we advise calling it tsconfig.eslint.json) in your project root which lists this file in its include. For an example of this, you can check out the configuration we previously used in this repo:

More Details

This error may appear from the combination of two things:

  • The ESLint configuration for the source file specifies at least one TSConfig file in parserOptions.project
  • None of those TSConfig files includes the source file being linted

When TSConfig files are specified for parsing a source file, @typescript-eslint/parser will use the first TSConfig that is able to include that source file (per aka.ms/tsconfig#include) to generate type information. However, if no specified TSConfig includes the source file, the parser won't be able to generate type information.

This error most commonly happens on config files or similar that are not included in their project TSConfig(s). For example, many projects have files like:

  • An .eslintrc.cjs / eslint.config.mjs with parserOptions.project: true
  • A tsconfig.json with include: ["src"]

In that case, viewing the file in an IDE with the ESLint extension will show the error notice that the file couldn't be linted because it isn't included in tsconfig.json.

See our docs on type aware linting for more information.

I get errors telling me "The file must be included in at least one of the projects provided"

You're using an outdated version of @typescript-eslint/parser. Update to the latest version to see a more informative version of this error message, explained above.