Skip to content

Bug: base config should have TS files. #11291

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
4 tasks done
kirkwaiblinger opened this issue Jun 10, 2025 · 2 comments
Open
4 tasks done

Bug: base config should have TS files. #11291

kirkwaiblinger opened this issue Jun 10, 2025 · 2 comments
Labels
bug Something isn't working package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin package: typescript-eslint Issues related to the typescript-eslint package preset config change Proposal for an addition, removal, or general change to a preset config triage Waiting for team members to take a look

Comments

@kirkwaiblinger
Copy link
Member

kirkwaiblinger commented Jun 10, 2025

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.

Issue Description

I expect the following config to work for linting TS files, but, instead, eslint issues an error ("File ignored because no matching configuration was supplied") when linting a TS file. This is due to the fact that eslint requires a file to be included in at least one config object's files field in order to be linted.

import tseslint from 'typescript-eslint';

export default tseslint.config(
    tseslint.configs.base,
    {
        rules: {
            '@typescript-eslint/no-unused-vars': 'error',
        }
    }
);

Right now, the description for the base config (link) says

A minimal ruleset that sets only the required parser and plugin options needed to run typescript-eslint.

Technically, that's true, but it doesn't set all the options required to run typescript-eslint on TS files. Surprisingly, this is only done in the rest of our configs by virtue of the fact that they include the eslint-recommended config, which has files set primarily in order to disable eslint core rules.

To see this, note that the following errors on TS files:

export default tseslint.config(
    (() => {
        const recommendedCopy = [...tseslint.configs.recommended];
        recommendedCopy.splice(1, 1); // remove the eslint-recommended config
        return recommendedCopy;
    })(),
);

I propose - let's add files: ['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'] to the base config so that it enables linting on TS files.

Reproduction Repository Link

https://github.com/kirkwaiblinger/tseslint-base-files-repro/

Repro Steps

  1. clone the repo
  2. npm i
  3. npm test

Versions

all version of eslint 9 and typescript-eslint 8 that I tried

Specifically, repros on latest:

    "eslint": "9.28.0",
    "typescript-eslint": "8.34.0"
@kirkwaiblinger kirkwaiblinger added bug Something isn't working triage Waiting for team members to take a look package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin preset config change Proposal for an addition, removal, or general change to a preset config package: typescript-eslint Issues related to the typescript-eslint package labels Jun 10, 2025
@bradzacher
Copy link
Member

we purposely never added any files to any of our configs because there are usecases like vue that have .vue extensions -- so if we restrict the globs to certain extensions then we lock those users out.

additionally all of our rules work fine on JS files -- so restricting them to just TS files wasn't necessary. People always wrote "TS-first" lint configs and left .js as an exception.

The only files we have has actually always just been via eslint-recommended:

files:
style === 'glob'
? // classic configs use glob syntax
['*.ts', '*.tsx', '*.mts', '*.cts']
: // flat configs use minimatch syntax
['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'],

The reason we gated this was because it was always a small list of rules that were provably safe to disable on TS files. But because we can't vouch for other languages we always gated them.

This also had the benefit of being an easy way to automatically make .ts files get enabled by default in ESLint.

Personally I'd say "probably not a good idea" to adding a files to base:

  • if we add it alongside (i.e. convert the config to an array) then that's a breaking change as consumers would need to change their config files with the version bump.
  • if we add it to the single object then that's a breaking change as it limits the config from working on exotic extensions.

@kirkwaiblinger
Copy link
Member Author

we purposely never added any files to any of our configs because there are usecases like vue that have .vue extensions -- so if we restrict the globs to certain extensions then we lock those users out.

additionally all of our rules work fine on JS files -- so restricting them to just TS files wasn't necessary. People always wrote "TS-first" lint configs and left .js as an exception.

Fully aligned

The only files we have has actually always just been via eslint-recommended:
[...]
This also had the benefit of being an easy way to automatically make .ts files get enabled by default in ESLint.

This is the part that I find pretty unexpected as a user. I'd have thought that base would include a "global includes" for TS files, so to speak, so that I'd just need to specify rules after that point in order for them to apply to TS files. Relying on eslint-recommended seems... odd. If I'm an individual-rule-choosing-user, I guess I'd do this? 😢

export default tseslint.config(
   // enable TS lang support
   tseslint.configs.base,
   // enable linting of TS files
   { files: tseslint.configs['eslint-recommended'].files },
   {  
      rules: { /* etc */ },
   },
);

Personally I'd say "probably not a good idea" to adding a files to base:

  • if we add it alongside (i.e. convert the config to an array) then that's a breaking change as consumers would need to change their config files with the version bump.

Blehhhh, behavior-wise, I was thinking it would be ok, but I totally forgot about the object -> array shape change being breaking 🙃. tseslint.config()/defineConfig() really proving their worth here over raw export default [tseslint.configs.base].

  • if we add it to the single object then that's a breaking change as it limits the config from working on exotic extensions.

Aligned, yeah it would only make sense as a separate config object.


So, definitely agreed there isn't really anything we can do without a breaking change (short of creating a new config altogether, which is totally unwarranted). Maybe something to consider for v9?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin package: typescript-eslint Issues related to the typescript-eslint package preset config change Proposal for an addition, removal, or general change to a preset config triage Waiting for team members to take a look
Projects
None yet
Development

No branches or pull requests

2 participants