This error occurs when using a @typescript-eslint rule that needs type information but the ESLint parser isn't configured to provide it. You need to configure parserOptions.projectService or parserOptions.project in your ESLint config to enable typed linting.
The "@typescript-eslint rule requires parser" error happens when you enable ESLint rules that need TypeScript's type system to work, but your ESLint configuration doesn't tell the parser how to access TypeScript's type information. Rules like @typescript-eslint/no-floating-promises, @typescript-eslint/no-misused-promises, and @typescript-eslint/await-thenable require type information to analyze your code correctly. TypeScript-ESLint has two modes: syntactic rules (which only need to parse the code structure) and type-aware rules (which need full TypeScript type information). Type-aware rules are more powerful because they can catch semantic errors that purely syntactic analysis would miss, but they require additional configuration. The full error message typically says: "You have used a rule which requires parserServices to be generated. You must therefore provide a value for the 'parserOptions.project' property for @typescript-eslint/parser." This means ESLint needs to know where your tsconfig.json is located so it can create a TypeScript program with full type information.
The modern approach is to use projectService which automatically detects your tsconfig.json:
// .eslintrc.js or eslint.config.js
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
projectService: true,
tsconfigRootDir: __dirname,
},
plugins: ['@typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
],
};For flat config (ESLint 9+):
// eslint.config.js
import tseslint from '@typescript-eslint/eslint-plugin';
import parser from '@typescript-eslint/parser';
export default [
{
files: ['**/*.ts', '**/*.tsx'],
languageOptions: {
parser: parser,
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
plugins: { '@typescript-eslint': tseslint },
rules: tseslint.configs['recommended-requiring-type-checking'].rules,
},
];This approach is simpler and uses the same type information your IDE sees.
If you need more control or are using an older version, specify the tsconfig path directly:
// .eslintrc.js
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: './tsconfig.json',
tsconfigRootDir: __dirname,
},
plugins: ['@typescript-eslint'],
extends: [
'plugin:@typescript-eslint/recommended-requiring-type-checking',
],
};For monorepos with multiple tsconfig files:
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: [
'./tsconfig.json',
'./packages/*/tsconfig.json',
],
tsconfigRootDir: __dirname,
},
};You can also use project: true to auto-detect the nearest tsconfig.json for each file:
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: true,
tsconfigRootDir: __dirname,
},
};The files you're linting must be included in your TypeScript configuration:
// tsconfig.json
{
"compilerOptions": {
"strict": true,
// ... other options
},
"include": [
"src/**/*",
"tests/**/*",
"*.config.ts"
],
"exclude": [
"node_modules",
"dist",
"build"
]
}If ESLint tries to lint files outside this scope (like .eslintrc.js itself), you'll get errors. Create a separate tsconfig specifically for ESLint if needed:
// tsconfig.eslint.json
{
"extends": "./tsconfig.json",
"include": [
"src/**/*",
"tests/**/*",
"*.config.ts",
".eslintrc.ts"
]
}Then reference it in your ESLint config:
module.exports = {
parserOptions: {
project: './tsconfig.eslint.json',
},
};Ensure you have recent versions of the required packages. The projectService option requires @typescript-eslint v6.21.0 or later:
# Check current versions
npm list @typescript-eslint/parser @typescript-eslint/eslint-plugin
# Update to latest versions
npm install --save-dev @typescript-eslint/parser@latest @typescript-eslint/eslint-plugin@latest
# Or with specific versions (v7+ recommended)
npm install --save-dev @typescript-eslint/parser@^7.0.0 @typescript-eslint/eslint-plugin@^7.0.0Also ensure TypeScript itself is up to date:
npm install --save-dev typescript@latestAfter updating, restart your ESLint server (in VS Code: Cmd/Ctrl + Shift + P > "ESLint: Restart ESLint Server").
If you have files that shouldn't be type-checked (like config files), you can disable type-aware rules for them:
// .eslintrc.js
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
projectService: true,
tsconfigRootDir: __dirname,
},
overrides: [
{
// Disable type-aware rules for config files
files: ['*.config.js', '.eslintrc.js'],
parserOptions: {
projectService: false,
},
rules: {
'@typescript-eslint/no-floating-promises': 'off',
'@typescript-eslint/no-misused-promises': 'off',
},
},
],
};Or use ESLint's ignore patterns:
// .eslintrc.js
module.exports = {
ignorePatterns: ['*.config.js', 'scripts/*.js'],
// ... rest of config
};Double-check that your ESLint config explicitly specifies the TypeScript parser:
// .eslintrc.js - CORRECT
module.exports = {
parser: '@typescript-eslint/parser', // ✓ Required
parserOptions: {
projectService: true,
},
};
// WRONG - missing parser
module.exports = {
parserOptions: {
projectService: true, // ✗ Won't work without parser
},
};For flat config format:
// eslint.config.js - CORRECT
import parser from '@typescript-eslint/parser';
export default [
{
languageOptions: {
parser: parser, // ✓ Required
parserOptions: {
projectService: true,
},
},
},
];Clear your ESLint cache if changes aren't taking effect:
# Remove ESLint cache
rm -rf .eslintcache
rm -rf node_modules/.cache/eslint
# Re-run ESLint
npx eslint . --fix### Performance Considerations
Type-aware linting is significantly slower than syntactic-only linting because it requires TypeScript to build a full program with type information. For large projects, this can add several seconds to lint time.
Optimization strategies:
1. Use projectService over project: The projectService option is faster because it reuses TypeScript's incremental compilation.
2. Limit type-aware rules to critical files: Use overrides to only enable typed rules where they matter:
module.exports = {
overrides: [
{
files: ['src/**/*.ts'],
parserOptions: { projectService: true },
extends: ['plugin:@typescript-eslint/recommended-requiring-type-checking'],
},
{
files: ['tests/**/*.ts'],
parserOptions: { projectService: false }, // Faster for tests
},
],
};3. Use `.eslintignore` to exclude generated files: Don't lint build outputs, migrations, or auto-generated code.
### Differences Between projectService and project
| Feature | projectService | project |
|---------|---------------|---------|
| Configuration | Auto-detects tsconfig.json | Requires explicit path(s) |
| Performance | Faster (reuses TypeScript server) | Slower (creates new programs) |
| Editor consistency | Matches IDE types exactly | May differ from IDE |
| Monorepo support | Automatic | Manual paths needed |
| Min version | @typescript-eslint 6.21.0+ | All versions |
### Common Type-Aware Rules
Rules that require parser services include:
- Promise handling: no-floating-promises, no-misused-promises, promise-function-async
- Boolean logic: strict-boolean-expressions, no-unnecessary-condition
- Type safety: no-unsafe-assignment, no-unsafe-member-access, no-unsafe-call
- Async/await: await-thenable, no-misused-await
- Type narrowing: prefer-nullish-coalescing, prefer-optional-chain
You can check which rules require type information in the [typescript-eslint documentation](https://typescript-eslint.io/rules/?=xrequires-type-information).
### Debugging Parser Issues
If you're still having trouble, use TypeScript's trace to see what's happening:
# See which files TypeScript is compiling
npx tsc --listFiles
# Trace module resolution
npx tsc --traceResolution | grep tsconfigEnable ESLint's debug mode:
DEBUG=eslint:cli-engine npx eslint src/### Working with Monorepos
For monorepos with multiple packages, use project arrays or auto-detection:
// Root .eslintrc.js
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
// Option 1: Auto-detect (recommended)
project: true,
tsconfigRootDir: __dirname,
// Option 2: Explicit paths
// project: [
// './tsconfig.json',
// './packages/*/tsconfig.json',
// './apps/*/tsconfig.json',
// ],
},
};Each package can have its own ESLint config that extends the root:
// packages/my-package/.eslintrc.js
module.exports = {
extends: '../../.eslintrc.js',
parserOptions: {
project: './tsconfig.json',
tsconfigRootDir: __dirname,
},
};### ESLint Flat Config Migration
If migrating to ESLint 9's flat config format:
// eslint.config.js
import tseslint from 'typescript-eslint';
export default tseslint.config(
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
...tseslint.configs.recommendedTypeChecked,
);The typescript-eslint package provides helper functions for flat config.
Function expression requires a return type
Function expression requires a return type
Value of type 'string | undefined' is not iterable
How to fix "Value is not iterable" in TypeScript
Type 'undefined' is not assignable to type 'string'
How to fix "Type undefined is not assignable to type string" in TypeScript
Type narrowing from typeof check produces 'never'
How to fix "Type narrowing produces never" in TypeScript
Type parameter 'T' has conflicting constraints
How to fix "Type parameter has conflicting constraints" in TypeScript