Conversation
✅ Deploy Preview for docs-eslint ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull Request Overview
This PR introduces extendable type support for plugin rules and settings by updating the core dependency and adding corresponding documentation.
- Bumps the
@eslint/coreversion to enable newRulesConfigandSettingsConfigtypes - Adds docs showing how to augment
RulesConfigandSettingsConfigin plugins
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| package.json | Updated @eslint/core dependency from ^0.14.0 to ^0.15.0 |
| docs/src/extend/plugins.md | Added sections and examples for extending RulesConfig and SettingsConfig |
Comments suppressed due to low confidence (2)
docs/src/extend/plugins.md:194
- There’s an extra
{here in the code snippet. Remove it or wrap these entries in the proper object/array structure so the example compiles.
{
docs/src/extend/plugins.md:424
- This snippet also has an extra
{. Adjust the example to show a validdefineConfigcall with the correct object or array nesting.
{
| type RuleEntry<Options extends any[] = any[]> = | ||
| | RuleSeverity | ||
| | RuleSeverityAndOptions<Options>; | ||
| type RuleEntry<Options extends any[] = any[]> = RuleConfig<Options>; |
There was a problem hiding this comment.
To eliminate duplication and avoid a breaking change.
| interface RulesRecord { | ||
| [rule: string]: RuleEntry; | ||
| } | ||
| type RulesRecord = RulesConfig; |
There was a problem hiding this comment.
Same here. Don't want to delete the type, just alias the new type instead.
| * @see [Settings](https://eslint.org/docs/latest/use/configure/configuration-files-deprecated#adding-shared-settings) | ||
| */ | ||
| settings?: { [name: string]: any } | undefined; | ||
| settings?: SettingsConfig | undefined; |
There was a problem hiding this comment.
This is the interface of eslintrc configs. I think this change should be made here instead:
Line 1832 in 00e3e6a
|
|
||
| declare module "@eslint/core" { | ||
| interface RulesConfig { | ||
| "example/dollar-sign": RuleConfig<["always" | "never"]>; |
There was a problem hiding this comment.
| "example/dollar-sign": RuleConfig<["always" | "never"]>; | |
| "example/dollar-sign": RuleConfig<Partial<["always" | "never"]>>; |
Otherwise, a configuration like "example/dollar-sign": ["error"] would be invalid.
There was a problem hiding this comment.
Are you sure about that? RuleConfig is defined as follows:
To me, that reads like just having a severity would still be valid even without Partial?
There was a problem hiding this comment.
To me, that reads like just having a severity would still be valid even without
Partial?
It would be valid as the whole value, i.e., not wrapped in an array.
I was testing this way:
// eslint.config.ts
import type { RuleConfig } from "@eslint/core";
declare module "@eslint/core" {
interface RulesConfig {
"example/dollar-sign": RuleConfig<["always" | "never"]>;
}
}
import { defineConfig } from "eslint/config";
//import example from "eslint-plugin-example";
export default defineConfig([
{
files: ["**/*.js"],
//plugins: { example },
rules: {
"example/dollar-sign": ["error"],
},
},
]);There was a problem hiding this comment.
Ah, I see! It seems like we could modify RuleConfig like this:
export type RuleConfig<RuleOptions extends unknown[] = unknown[]> =
| Severity
+ | [Severity]
| [Severity, ...RuleOptions];It would be one less thing rule developers need to remember?
There was a problem hiding this comment.
Perhaps that should have been Severity | [Severity, ...Partial<RuleOptions>] so that rule types don't need to make options optional. Though that would assume that options are always optional, which doesn't necessarily has to be the case.
There was a problem hiding this comment.
To have the eslint package import the ESM version of the @eslint/core types, it's also possible to use the resolution-mode import attribute, which is stable since TypeScript 5.3 according to the docs. That would be this change in lib/types/index.d.ts:
-} from "@eslint/core";
+} from "@eslint/core" with { "resolution-mode": "import" };And in that case we'd probably need a new .mts test file to test the extendable interface inside an ESM module.
I tested this method and it passed both npm run test:types and npm run lint:types (after moving the new tests to an .mts file). I haven't checked the type integration tests though.
There was a problem hiding this comment.
Ooh nice!
I suppose the question then is which TypeScript versions do we want to support?
There was a problem hiding this comment.
Good question. Currently, we don't have a statement or policy that specifies which TypeScript versions are supported, unlike what we have for Node.js or jiti. I think it would be good to add this for TypeScript as well, regardless of which features we choose to support.
As far as I know, there's no reliable way to import types from an ESM module into a CommonJS module that works without resolution-mode. So, if we want to support TypeScript versions before 5.3, we'll need to stick to CommonJS-style core types. Alternatively, we could switch the ESLint types to ESM, but that would only make sense if we convert the whole repo to ESM.
There was a problem hiding this comment.
Supporting a minimum TypeScript version is a lot less work than converting the package to ESM, so let's discuss that option:
#19920
There was a problem hiding this comment.
Now that TypeScript < 5.3 is no longer supported and the CommonJS core types re-export the ESM types I think it should be fine to move forward with this PR. Some of the comments in this thread seem no longer relevant.
|
Per 2025-06-23 meeting, @mdjermanovic will investigate further into this. |
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Milos Djermanovic <[email protected]>
Co-authored-by: Milos Djermanovic <[email protected]>
Co-authored-by: Milos Djermanovic <[email protected]>
Co-authored-by: Milos Djermanovic <[email protected]>
Co-authored-by: Milos Djermanovic <[email protected]>
Co-authored-by: Milos Djermanovic <[email protected]>
mdjermanovic
left a comment
There was a problem hiding this comment.
LGTM, thanks! Leaving it open for @fasttime to verify.
Co-authored-by: Francesco Trotta <[email protected]>
Co-authored-by: Francesco Trotta <[email protected]>
|
Oops, I didn't see #19843 (comment) |
This reverts commit a04cc99. Now using `svelte.config.ts`, but you cannot import a TypeScript file in a JavaScript file. Seems eslint/eslint#19843 would be needed before we can switch to `eslint.config.ts`.
|
@Shinigami92 there's a lot we need to figure out before we can ship this: |
|
Hi everyone, it looks like we lost track of this pull request. Please review and see what the next steps are. This pull request will auto-close in 7 days without an update. |
fasttime
left a comment
There was a problem hiding this comment.
There are merge conflicts in the type declarations (index.d.ts) and in package.json, but it looks like all changes in those two files have been already incorporated in the main branch a while ago, so the remaining work is likely just updating documentation and type tests.

Prerequisites checklist
What is the purpose of this pull request? (put an "X" next to an item)
[x] Documentation update
[ ] Bug fix (template)
[ ] New rule (template)
[ ] Changes an existing rule (template)
[ ] Add autofix to a rule
[ ] Add a CLI option
[x] Add something to the core
[ ] Other, please explain:
What changes did you make? (Give an overview)
@eslint/coreRulesConfigandSettingsConfigfrom@eslint/corefixes #19721
fixes #19662
Is there anything you'd like reviewers to focus on?
One thing I couldn't figure out how to do was how to merge all of the rule config entries from
rules.d.tsinto theRulesConfigfrom@eslint/corewithout duplicating the code. I think that would be ideal, but I don't think it's a blocker for this PR.