TypeScript ESLint
typescript-eslint is a comprehensive tooling ecosystem that enables ESLint to lint TypeScript code. It integrates the TypeScript compiler's type information with ESLint's powerful static analysis capabilities, allowing developers to enforce code style, best practices, and catch logical errors specifically within TypeScript projects. The project is actively maintained, with frequent patch releases occurring weekly and minor versions released as needed. Major versions are released non-periodically to accommodate breaking changes or significant feature additions. Currently stable at version 8.58.2, typescript-eslint differentiates itself by providing over 100 specialized rules and robust support for modern ESLint 'flat' configurations, making it the de-facto standard for type-aware linting in the TypeScript ecosystem. It complements the TypeScript compiler by focusing on code quality and stylistic issues beyond pure type checking.
Common errors
-
ESLint was configured to run on <file-path> using 'parserOptions.project'. However, that TSConfig does not / none of those TSConfigs include this file.
cause The linted file is not included in the TypeScript project(s) specified in `parserOptions.project` in your ESLint configuration, preventing type information from being generated.fixAdd the file's path to the `include` array in your `tsconfig.json`. If the file should not be type-checked (e.g., a JavaScript file or a configuration file), use ESLint's `ignorePatterns` or an `overrides` block in your `.eslintrc.js` to exclude it from type-aware linting. -
Unexpected global require.
cause The `no-require-imports` rule (often enabled in recommended configs) disallows `require()` invocations, promoting ES Module `import` syntax.fixReplace `require()` calls with ES Module `import` statements (e.g., `import * as Module from 'module';` or `import { Name } from 'module';`). If you need to import JSON files outside of your TS root or in environments that don't support JSON modules, configure the `allow` option of the `no-require-imports` rule. -
'<variable>' is not defined. (no-undef)
cause The ESLint core `no-undef` rule does not use TypeScript's type information to determine global variables. This often leads to false positives in TypeScript projects, especially for globally declared types or namespaces.fixDisable the ESLint core `no-undef` rule and rely on TypeScript's built-in checks instead. TypeScript provides superior global variable checking. If you have global types from third-party `@types` packages, you might need to configure ESLint's `env` or `globals` settings. -
x is not assignable to type Y. Type 'A' is not assignable to type 'B'.
cause This is a general TypeScript type error, not an ESLint specific error. It indicates a type mismatch detected by the TypeScript compiler itself, which ESLint then reports through its parser services if type-aware rules are enabled.fixThis requires addressing the underlying TypeScript type incompatibility in your code. Consult TypeScript documentation on type safety, refactor your code to ensure correct type assignments, or use type assertions (`as Type`) or non-null assertions (`!`) judiciously if you are certain of the type. Reviewing relevant `typescript-eslint` rules like `no-explicit-any` or `no-unsafe-*` can help.
Warnings
- breaking Version 8 introduced breaking changes to its peer dependency requirements. ESLint must be `^8.57.0 || ^9.0.0 || ^10.0.0`, Node.js must be `^18.18.0 || ^20.9.0 || >=21.1.0`, and TypeScript must be `>=4.8.4 <6.1.0`.
- breaking The `@typescript-eslint/ban-types` rule was removed and replaced with more targeted rules in v8, namely `@typescript-eslint/no-restricted-types`, `@typescript-eslint/no-empty-object-type`, `@typescript-eslint/no-unsafe-function-type`, and `@typescript-eslint/no-wrapper-object-types`. The `prefer-ts-expect-error` rule was also removed in favor of `ban-ts-comment`.
- breaking The default configurations (`tseslint.configs.recommended`, `strict`, `all`) have been updated in v8, which may introduce new linting errors or changes in behavior. This is a common occurrence in major version upgrades.
- gotcha Using `parserOptions.project` for type-aware linting requires that all linted files are explicitly included in one of the specified `tsconfig.json` files. Files not included will lead to errors like 'ESLint was configured to run... However, that TSConfig does not / none of those TSConfigs include this file'.
- gotcha ESLint's built-in `--cache` option is generally not recommended for projects using `typescript-eslint`'s type-aware rules. The cache mechanism doesn't reliably account for cross-file type dependencies, leading to potentially stale or incorrect linting results.
- deprecated TypeScript 5.0 deprecated the `importsNotUsedAsValues` `tsconfig.json` option. While `typescript-eslint` still provides the `consistent-type-imports` rule, relying on the compiler option is no longer advised.
Install
-
npm install typescript-eslint -
yarn add typescript-eslint -
pnpm add typescript-eslint
Imports
- tseslint
const tseslint = require('typescript-eslint');import tseslint from 'typescript-eslint';
- defineConfig
import { defineConfig } from 'eslint/config'; - js.configs.recommended
import js from '@eslint/js';
Quickstart
/* eslint.config.mjs */
// @ts-check
import js from '@eslint/js';
import tseslint from 'typescript-eslint';
import { defineConfig } from 'eslint/config';
export default defineConfig(
js.configs.recommended,
...tseslint.configs.recommended,
{
files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
languageOptions: {
parserOptions: {
project: true,
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
// Example custom rule: enforce consistent usage of type imports
'@typescript-eslint/consistent-type-imports': 'error',
// Example: disable a base ESLint rule that has a TypeScript equivalent
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': [
'warn',
{ 'argsIgnorePattern': '^_' }
]
},
}
);
/* Example tsconfig.json */
// {
// "compilerOptions": {
// "target": "ES2022",
// "module": "ESNext",
// "esModuleInterop": true,
// "forceConsistentCasingInFileNames": true,
// "strict": true,
// "skipLibCheck": true,
// "jsx": "react-jsx",
// "lib": ["ES2022", "DOM", "DOM.Iterable"],
// "include": ["src"]
// }
// }