Skip to content

[Bug]: Type-aware rules are silently ignored if tsconfig.json was not found for that TypeScript file #1225

Description

@swwind

Details

In a typical TypeScript monorepo setup, the root tsconfig.json is configured as a solution-style config containing only references pointing to package-specific config files (e.g., tsconfig.node.json), with its own files set to empty:

{
  "files": [],
  "references": [
    { "path": "./tsconfig.node.json" }
  ]
}

When running linter checks from the workspace root, type-aware rules (like @typescript-eslint/no-floating-promises) require compiler program resolution. However, neither rslint nor standard file-based eslint configurations follow root project references by default.

The Problem: Silent Failure in rslint

While both linters fail to match the source file against the root tsconfig.json under basic setups, their feedback mechanisms differ significantly:

  • rslint fails silently: It silently skips type-aware rules for files not matched in the tsconfig, outputting 0 warnings or errors. Developers are left unaware that type checks are not being run on their files.
  • ESLint reports explicit errors: Depending on the configuration, ESLint will loudly report parsing errors or require explicit configuration, ensuring configuration issues do not go unnoticed.

Detailed Linter Behavior Comparison

Linter Configuration Scenario Behavior (When target file index.ts is only in referenced tsconfig.node.json)
rslint project: ["./tsconfig.json"] Silently ignores type-aware rules for index.ts. Reports 0 errors/warnings for no-floating-promises.
rslint project: ["./tsconfig.node.json"] Succeeds in linting: correctly matches index.ts using the sub-project tsconfig.
rslint projectService: true Silently ignores type-aware rules for index.ts. Reports 0 errors/warnings for no-floating-promises.
ESLint project: ["./tsconfig.json"] Fails loudly with parser error: The file was not found in any of the provided project(s): index.ts.
ESLint project: ["./tsconfig.node.json"] Succeeds in linting: correctly matches index.ts using the sub-project tsconfig.
ESLint project: true (Auto-lookup) Fails loudly after discovering the root tsconfig.json and failing to locate the file in its scope.
ESLint projectService: true Succeeds in linting: it follows references and finds the correct tsconfig.json automatically.
oxlint --type-aware Succeeds gracefully (*)

(*) Oxlint Behavior: Search for tsconfig.json upwards, recursively trace references, and if still not matched (or missing completely), fall back to CreateInferredProjectProgram (an in-memory compilation program with ES2022, StrictNullChecks, etc.).

Proposed Solutions for rslint

Warn/Fail: If a tsconfig.json is not found for a TypeScript file, log a warning/error indicating that type-aware lint rules were skipped for the file because it isn't part of the target tsconfig project structure. Force user to modify the config file, or manually ignore that in allowDefaultProject field or global ignores.

Reproduce link

https://github.com/swwind/rslint-reference-repro

Reproduce Steps

  1. Set up a project structure where tsconfig.json contains references only:
    tsconfig.json:
    {
      "files": [],
      "references": [
        { "path": "./tsconfig.node.json" }
      ]
    }
    tsconfig.node.json:
    {
      "include": ["index.ts"]
    }
  2. Create an index.ts with a floating promise and a syntax error:
    console.log("233");
    async function getPromise() {}
    getPromise(); // Floating promise
  3. Run rslint with the following rslint.config.ts (configured with the root tsconfig.json):
    import { defineConfig } from "@rslint/core";
    export default defineConfig([
      {
        files: ["**/*.ts"],
        plugins: ["@typescript-eslint"],
        languageOptions: {
          parserOptions: { project: ["./tsconfig.json"] },
        },
        rules: {
          "no-console": "error",
          "@typescript-eslint/no-floating-promises": "error",
        },
      },
    ]);
  4. Run rslint. It only reports the no-console error but silently skips the @typescript-eslint/no-floating-promises error on index.ts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions