Skip to content

Bug: "Single run" not resolving types / resolving incorrect libs #5136

Closed
@milesj

Description

@milesj

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.
  • I have searched for related issues and found none that matched my issue.
  • I have read the FAQ and my problem is not listed.

Relevant Package

parser

Playground Link

No response

Repro Code

I'm not sure what the conditions are to reproduce this yet.

ESLint Config

module.exports = {
  parser: "@typescript-eslint/parser",
  parserOptions: {
    // This path changes based on which folder the eslint binary is running in
    project: ['path/to/tsconfig.json'],
    tsconfigRootDir: __dirname,
    allowAutomaticSingleRunInference: true,
  },
  extends: ['airbnb', 'import', 'react', 'react-hooks', 'jest', '@typescript-eslint'],
  reportUnusedDisableDirectives: true,
  rules: {
    // Pretty much all the rules provided by the plugins/configs
  },
};

tsconfig

{
  "compilerOptions": {
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "baseUrl": ".",
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "forceConsistentCasingInFileNames": true,
    "jsx": "react-jsx",
    "isolatedModules": true,
    "lib": [
      "dom",
      "esnext"
    ],
    "module": "CommonJS",
    "moduleResolution": "node",
    "noFallthroughCasesInSwitch": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "sourceMap": true,
    "strict": true,
    "target": "ES2020",
  },
  "include": [
    "**/*"
  ]
}

Expected Result

When using allowAutomaticSingleRunInference or TSESTREE_SINGLE_RUN=true, types and lints resolve/pass correctly, in the same manner as if these settings were turned off.

Actual Result

When using allowAutomaticSingleRunInference or TSESTREE_SINGLE_RUN=true, we've noticed that types (mainly @types) spuriously fail to resolve. For example, useMemo from import { useMemo } from 'react' resolves to any, causing our @typescript-eslint/no-unsafe-* to fail.

When looking at the debug logs, we noticed that the resolved libs are not what we configured (the esnext.full is no where to be found in our repo). Once this incorrect lib is used, types start failing. Here's an excerpt from the logs:

eslint:cli-engine Lint <path>/config/atomic.ts +8ms
typescript-eslint:typescript-estree:parser parserOptions.project (excluding ignored) matched projects: Set(1) {
	'<path>/tsconfig.json'
} +7ms
typescript-eslint:typescript-estree:useProvidedProgram Retrieving ast for <path>/config/atomic.ts from provided program instance(s) +7ms
typescript-eslint:parser:parser Resolved libs from program: [ 'dom', 'esnext' ] +8ms

eslint:cli-engine Lint <path>/config/device.ts +5ms
typescript-eslint:typescript-estree:parser parserOptions.project (excluding ignored) matched projects: Set(1) {
	'<path>/tsconfig.json'
} +5ms
typescript-eslint:typescript-estree:createIsolatedProgram Getting isolated program in TS mode for: <path>/config/device.ts +41ms
typescript-eslint:parser:parser Resolved libs from program: [ 'esnext.full' ] +6ms
typescript-eslint:eslint-plugin:utils:types Found an "error" any type +92ms
typescript-eslint:eslint-plugin:utils:types Found an "error" any type +1ms
typescript-eslint:eslint-plugin:utils:types Found an "error" any type +0ms
typescript-eslint:eslint-plugin:utils:types Found an "error" any type +0ms
typescript-eslint:eslint-plugin:utils:types Found an "error" any type +1ms
typescript-eslint:eslint-plugin:utils:types Found an "error" any type +0ms
typescript-eslint:eslint-plugin:utils:types Found an "error" any type +0ms

eslint:cli-engine Lint <path>/config/keys.ts +17ms
typescript-eslint:typescript-estree:parser parserOptions.project (excluding ignored) matched projects: Set(1) {
	'<path>/tsconfig.json'
} +18ms
typescript-eslint:typescript-estree:useProvidedProgram Retrieving ast for <path>/config/keys.ts from provided program instance(s) +23ms
typescript-eslint:parser:parser Resolved libs from program: [ 'dom', 'esnext' ] +16ms

Notice that config/device.ts creates a new isolated program with esnext.full, instead of reusing an existing program like config/atomic.ts and config/keys.ts does, which is dom, esnext. All of these files are in the same program, even the same folder.

HOWEVER! When I run the linter on config/device.ts individually, the linting passes correctly.

eslint:cli-engine Lint <path>/config/device.ts +0ms
typescript-eslint:typescript-estree:parser parserOptions.project (excluding ignored) matched projects: Set(1) {
	'<path>/tsconfig.json'
} +0ms
typescript-eslint:typescript-estree:useProvidedProgram Retrieving ast for <path>/config/device.ts from provided program instance(s) +0ms
typescript-eslint:typescript-estree:parser Detected single-run/CLI usage, creating Program once ahead of time for project: <path>/tsconfig.json +0ms
typescript-eslint:parser:parser Resolved libs from program: [ 'dom', 'esnext' ] +0ms
eslint:cli-engine Linting complete in: 3306ms +2s

This leads me to believe that the parser is losing the program? Or handling paths/detection wrong? I did some digging into node_modules but was unable to find the root cause.

Additional Info

Our codebase has over 10,000 files and this is consistently running out of memory, so this is me digging into alternatives/why it's happening.

Versions

package version
@typescript-eslint/eslint-plugin 5.26.0
@typescript-eslint/parser 5.26.0
@typescript-eslint/scope-manager 5.26.0
@typescript-eslint/typescript-estree 5.26.0
@typescript-eslint/type-utils 5.26.0
@typescript-eslint/utils 5.26.0
TypeScript 4.6.3
ESLint 8.16.0
node 16.13.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    awaiting responseIssues waiting for a reply from the OP or another partyquestionQuestions! (i.e. not a bug / enhancment / documentation)unable to reproissues that a maintainer was not able to reproduce

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions