Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/eslint/base.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Public preset: base — framework-agnostic full stack.
*
* ignores + typescript + quality + testing, then prettier last. For plain TS
* ignores + quality + typescript + testing, then prettier last. For plain TS
* libraries and Node packages with no Vue and no Workers runtime.
*
* Compose concerns directly instead if you want finer control:
Expand Down
6 changes: 4 additions & 2 deletions src/eslint/core.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Internal: the framework-agnostic core = ignores + typescript + quality +
* Internal: the framework-agnostic core = ignores + quality + typescript +
Comment thread
coderabbitai[bot] marked this conversation as resolved.
* testing + tooling relaxations. NOT exported directly and deliberately does
* NOT end with prettier — each public preset appends prettier last (after any
* framework layer) so no formatting rules survive.
Expand All @@ -12,8 +12,10 @@ import { TOOLING_FILES } from "./globs.js";

export default [
...ignores,
...typescript,
...quality,
// TypeScript must follow the JavaScript quality layer so its extension rules
// can disable overlapping core rules such as no-undef and no-unused-vars.
...typescript,
...testing,
{
files: TOOLING_FILES,
Expand Down
30 changes: 30 additions & 0 deletions test/typescript-core-rule-replacements.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import assert from "node:assert/strict";
import { test } from "node:test";

import { ESLint } from "eslint";

import nodePreset from "../src/eslint/node.js";

const eslint = new ESLint({
cwd: process.cwd(),
overrideConfig: nodePreset,
overrideConfigFile: true,
});

const severity = (rule) => rule?.[0] ?? 0;

test("TypeScript extension rules replace overlapping core rules", async () => {
const config = await eslint.calculateConfigForFile("fixture.ts");

assert.equal(severity(config.rules["no-undef"]), 0);
assert.equal(severity(config.rules["no-unused-vars"]), 0);
assert.equal(severity(config.rules["@typescript-eslint/no-unused-vars"]), 2);
});

test("plain JavaScript keeps equivalent correctness coverage", async () => {
const config = await eslint.calculateConfigForFile("fixture.js");

assert.equal(severity(config.rules["no-undef"]), 2);
assert.equal(severity(config.rules["no-unused-vars"]), 0);
assert.equal(severity(config.rules["@typescript-eslint/no-unused-vars"]), 2);
});