This error occurs when ESLint is configured to use @typescript-eslint/parser with type-aware linting (parserOptions.project), but tries to lint a file that isn't included in your TypeScript configuration. Files must be in your tsconfig.json's include array or you need to adjust ESLint's configuration to exclude them.
The "@typescript-eslint cannot parse file without TypeScript" error appears when ESLint attempts to apply type-aware linting rules to a file that isn't part of your TypeScript project. This happens because you've configured parserOptions.project in your ESLint config, which tells @typescript-eslint/parser to use TypeScript's type checker for enhanced linting rules. When parserOptions.project is set, ESLint needs to generate type information for each file using your tsconfig.json. If a file isn't included in that TypeScript configuration (or is explicitly excluded), the parser cannot build the type information and throws this error. This commonly occurs with configuration files (like .eslintrc.js, jest.config.js), build scripts, or files in directories that are intentionally excluded from TypeScript compilation. The error is actually a safety mechanism - it prevents ESLint from making incorrect type-based assumptions about files that TypeScript isn't supposed to process.
If the files should be type-checked, add them to your tsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"target": "es2020"
},
"include": [
"src/**/*",
"*.js", // Include root-level JS files
"scripts/**/*.ts", // Include scripts directory
"test/**/*.ts" // Include test files
]
}For projects with config files at root:
{
"include": [
"src",
".eslintrc.js",
"jest.config.js",
"*.config.js"
]
}After updating tsconfig.json, restart your IDE's TypeScript server.
Instead of modifying your main tsconfig.json, create a separate config for ESLint:
// tsconfig.eslint.json
{
"extends": "./tsconfig.json",
"include": [
"src/**/*",
"*.js",
"*.config.js",
".eslintrc.js",
"scripts/**/*",
"test/**/*"
]
}Then reference it in your ESLint config:
// .eslintrc.js
module.exports = {
parser: "@typescript-eslint/parser",
parserOptions: {
project: "./tsconfig.eslint.json",
tsconfigRootDir: __dirname,
},
// ... rest of config
};This approach keeps your TypeScript compilation config separate from your linting config.
Configure ESLint to use different parser settings for JavaScript config files:
// .eslintrc.js
module.exports = {
parser: "@typescript-eslint/parser",
parserOptions: {
project: "./tsconfig.json",
},
overrides: [
{
// Disable type-aware linting for JS files
files: ["*.js", "*.config.js"],
parserOptions: {
project: null, // Disable type checking
},
rules: {
"@typescript-eslint/no-var-requires": "off",
},
},
{
// Different config for test files
files: ["**/__tests__/**", "**/*.test.ts"],
parserOptions: {
project: "./tsconfig.test.json",
},
},
],
};This tells ESLint not to apply type-aware linting to files that aren't TypeScript source code.
If files shouldn't be linted at all, add them to .eslintignore:
# .eslintignore
node_modules/
dist/
build/
*.config.js
.eslintrc.js
coverage/
scripts/Or use ignorePatterns in .eslintrc.js:
module.exports = {
ignorePatterns: [
"dist",
"build",
"*.config.js",
".eslintrc.js",
"scripts/**/*",
],
// ... rest of config
};This completely skips ESLint processing for these files.
Ensure TypeScript is installed as a local dependency, not globally:
# Check if TypeScript is in package.json
cat package.json | grep typescript
# If not installed locally, add it
npm install --save-dev typescript
# Verify version
npx tsc --version
# For @typescript-eslint dependencies
npm install --save-dev @typescript-eslint/parser @typescript-eslint/eslint-pluginGlobal TypeScript installations can cause resolution issues with ESLint.
Modern @typescript-eslint/parser (v6+) supports projectService for simpler configuration:
// .eslintrc.js
module.exports = {
parser: "@typescript-eslint/parser",
parserOptions: {
projectService: true, // Automatically finds nearest tsconfig.json
tsconfigRootDir: __dirname,
},
plugins: ["@typescript-eslint"],
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended-type-checked",
],
};This automatically uses the nearest tsconfig.json for each file and is more forgiving with project structure.
For older versions, use project: true:
parserOptions: {
project: true,
tsconfigRootDir: __dirname,
}### Understanding parserOptions.project
The parserOptions.project setting enables type-aware linting rules like:
- @typescript-eslint/no-floating-promises
- @typescript-eslint/no-misused-promises
- @typescript-eslint/await-thenable
- @typescript-eslint/no-unnecessary-type-assertion
These rules require TypeScript's type checker to work. Setting project tells ESLint which tsconfig.json to use for type information. However, this comes with a cost: every file ESLint processes must be included in that TypeScript configuration.
Options for parserOptions.project:
// Single tsconfig
project: "./tsconfig.json"
// Multiple tsconfigs
project: ["./tsconfig.json", "./tsconfig.test.json"]
// Automatic detection (v6+)
project: true
// Automatic with projectService (v6.21.0+, recommended)
projectService: true### Performance Considerations
Type-aware linting is significantly slower than basic linting because it requires building TypeScript's type graph. For large projects:
Option 1: Selective type-aware linting
module.exports = {
extends: [
"plugin:@typescript-eslint/recommended", // Fast rules only
],
overrides: [
{
files: ["src/**/*.ts"],
extends: [
"plugin:@typescript-eslint/recommended-type-checked", // Slower, type-aware rules
],
parserOptions: {
project: "./tsconfig.json",
},
},
],
};Option 2: Use allowDefaultProject (not recommended for production)
parserOptions: {
project: "./tsconfig.json",
allowDefaultProject: true, // Allows linting files outside project
}This creates a default project for orphaned files but may produce incorrect type information.
### Monorepo Setup
For monorepos with multiple packages:
// Root .eslintrc.js
module.exports = {
parser: "@typescript-eslint/parser",
parserOptions: {
project: [
"./tsconfig.json",
"./packages/*/tsconfig.json",
],
tsconfigRootDir: __dirname,
},
};Or use projectService for automatic detection:
parserOptions: {
projectService: {
allowDefaultProject: ["*.js"],
defaultProject: "./tsconfig.json",
},
tsconfigRootDir: __dirname,
}### Debugging Configuration Issues
Check which files are included in your TypeScript project:
# List all files TypeScript sees
npx tsc --listFiles | grep -v node_modules
# Show detailed resolution
npx tsc --explainFilesEnable ESLint debug output:
DEBUG=eslint:* npx eslint src/Check @typescript-eslint parser version compatibility:
npm list @typescript-eslint/parser @typescript-eslint/eslint-plugin typescriptEnsure all three versions are compatible (same major version for parser and plugin).
### Common Gotchas
1. Case sensitivity in include patterns:
// Won't match *.JS files on Linux
"include": ["src/**/*.js"]
// Better: be explicit
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.js", "src/**/*.jsx"]2. Exclude takes precedence over include:
{
"include": ["src"],
"exclude": ["src/scripts"] // src/scripts won't be included
}3. Files outside project root:
If files are symlinked or outside your project root, use absolute paths or set tsconfigRootDir properly.
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