eslint-config-typed 2.3.2 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +319 -156
- package/dist/configs/plugins.d.mts +1 -1
- package/dist/configs/plugins.d.mts.map +1 -1
- package/dist/configs/plugins.mjs +5 -2
- package/dist/configs/plugins.mjs.map +1 -1
- package/dist/configs/react-base.d.mts.map +1 -1
- package/dist/configs/react-base.mjs +2 -0
- package/dist/configs/react-base.mjs.map +1 -1
- package/dist/configs/typescript-without-rules.mjs +4 -4
- package/dist/configs/typescript-without-rules.mjs.map +1 -1
- package/dist/configs/typescript.mjs +8 -8
- package/dist/configs/typescript.mjs.map +1 -1
- package/dist/entry-point.d.mts +1 -1
- package/dist/entry-point.d.mts.map +1 -1
- package/dist/entry-point.mjs +2 -1
- package/dist/entry-point.mjs.map +1 -1
- package/dist/index.mjs +3 -1
- package/dist/index.mjs.map +1 -1
- package/dist/plugins/index.d.mts +1 -0
- package/dist/plugins/index.d.mts.map +1 -1
- package/dist/plugins/index.mjs +1 -0
- package/dist/plugins/index.mjs.map +1 -1
- package/dist/plugins/react-coding-style/index.d.mts +2 -0
- package/dist/plugins/react-coding-style/index.d.mts.map +1 -0
- package/dist/plugins/react-coding-style/index.mjs +2 -0
- package/dist/plugins/react-coding-style/index.mjs.map +1 -0
- package/dist/plugins/react-coding-style/plugin.d.mts +3 -0
- package/dist/plugins/react-coding-style/plugin.d.mts.map +1 -0
- package/dist/plugins/react-coding-style/plugin.mjs +8 -0
- package/dist/plugins/react-coding-style/plugin.mjs.map +1 -0
- package/dist/plugins/react-coding-style/rules/ban-use-imperative-handle-hook.d.mts +5 -0
- package/dist/plugins/react-coding-style/rules/ban-use-imperative-handle-hook.d.mts.map +1 -0
- package/dist/plugins/react-coding-style/rules/ban-use-imperative-handle-hook.mjs +29 -0
- package/dist/plugins/react-coding-style/rules/ban-use-imperative-handle-hook.mjs.map +1 -0
- package/dist/plugins/react-coding-style/rules/component-name.d.mts +10 -0
- package/dist/plugins/react-coding-style/rules/component-name.d.mts.map +1 -0
- package/dist/plugins/react-coding-style/rules/component-name.mjs +78 -0
- package/dist/plugins/react-coding-style/rules/component-name.mjs.map +1 -0
- package/dist/plugins/react-coding-style/rules/component-var-type-annotation.d.mts +5 -0
- package/dist/plugins/react-coding-style/rules/component-var-type-annotation.d.mts.map +1 -0
- package/dist/plugins/react-coding-style/rules/component-var-type-annotation.mjs +41 -0
- package/dist/plugins/react-coding-style/rules/component-var-type-annotation.mjs.map +1 -0
- package/dist/plugins/react-coding-style/rules/import-style.d.mts +5 -0
- package/dist/plugins/react-coding-style/rules/import-style.d.mts.map +1 -0
- package/dist/plugins/react-coding-style/rules/import-style.mjs +45 -0
- package/dist/plugins/react-coding-style/rules/import-style.mjs.map +1 -0
- package/dist/plugins/react-coding-style/rules/index.d.mts +2 -0
- package/dist/plugins/react-coding-style/rules/index.d.mts.map +1 -0
- package/dist/plugins/react-coding-style/rules/index.mjs +2 -0
- package/dist/plugins/react-coding-style/rules/index.mjs.map +1 -0
- package/dist/plugins/react-coding-style/rules/props-type-annotation-style.d.mts +5 -0
- package/dist/plugins/react-coding-style/rules/props-type-annotation-style.d.mts.map +1 -0
- package/dist/plugins/react-coding-style/rules/props-type-annotation-style.mjs +44 -0
- package/dist/plugins/react-coding-style/rules/props-type-annotation-style.mjs.map +1 -0
- package/dist/plugins/react-coding-style/rules/react-memo-props-argument-name.d.mts +5 -0
- package/dist/plugins/react-coding-style/rules/react-memo-props-argument-name.d.mts.map +1 -0
- package/dist/plugins/react-coding-style/rules/react-memo-props-argument-name.mjs +55 -0
- package/dist/plugins/react-coding-style/rules/react-memo-props-argument-name.mjs.map +1 -0
- package/dist/plugins/react-coding-style/rules/react-memo-type-parameter.d.mts +5 -0
- package/dist/plugins/react-coding-style/rules/react-memo-type-parameter.d.mts.map +1 -0
- package/dist/plugins/react-coding-style/rules/react-memo-type-parameter.mjs +78 -0
- package/dist/plugins/react-coding-style/rules/react-memo-type-parameter.mjs.map +1 -0
- package/dist/plugins/react-coding-style/rules/rules.d.mts +14 -0
- package/dist/plugins/react-coding-style/rules/rules.d.mts.map +1 -0
- package/dist/plugins/react-coding-style/rules/rules.mjs +22 -0
- package/dist/plugins/react-coding-style/rules/rules.mjs.map +1 -0
- package/dist/plugins/react-coding-style/rules/shared.d.mts +5 -0
- package/dist/plugins/react-coding-style/rules/shared.d.mts.map +1 -0
- package/dist/plugins/react-coding-style/rules/shared.mjs +22 -0
- package/dist/plugins/react-coding-style/rules/shared.mjs.map +1 -0
- package/dist/plugins/react-coding-style/rules/use-memo-hooks-style.d.mts +5 -0
- package/dist/plugins/react-coding-style/rules/use-memo-hooks-style.d.mts.map +1 -0
- package/dist/plugins/react-coding-style/rules/use-memo-hooks-style.mjs +42 -0
- package/dist/plugins/react-coding-style/rules/use-memo-hooks-style.mjs.map +1 -0
- package/dist/plugins/total-functions/rules/common.d.mts +2 -1
- package/dist/plugins/total-functions/rules/common.d.mts.map +1 -1
- package/dist/plugins/total-functions/rules/fp-ts.d.mts +2 -1
- package/dist/plugins/total-functions/rules/fp-ts.d.mts.map +1 -1
- package/dist/plugins/total-functions/rules/unsafe-assignment-rule.d.mts +2 -1
- package/dist/plugins/total-functions/rules/unsafe-assignment-rule.d.mts.map +1 -1
- package/dist/rules/eslint-import-rules.d.mts +50 -47
- package/dist/rules/eslint-import-rules.d.mts.map +1 -1
- package/dist/rules/eslint-import-rules.mjs +55 -54
- package/dist/rules/eslint-import-rules.mjs.map +1 -1
- package/dist/rules/eslint-react-coding-style-rules.d.mts +13 -0
- package/dist/rules/eslint-react-coding-style-rules.d.mts.map +1 -0
- package/dist/rules/eslint-react-coding-style-rules.mjs +14 -0
- package/dist/rules/eslint-react-coding-style-rules.mjs.map +1 -0
- package/dist/rules/eslint-rules.d.mts +0 -57
- package/dist/rules/eslint-rules.d.mts.map +1 -1
- package/dist/rules/eslint-rules.mjs +1 -151
- package/dist/rules/eslint-rules.mjs.map +1 -1
- package/dist/rules/index.d.mts +1 -0
- package/dist/rules/index.d.mts.map +1 -1
- package/dist/rules/index.mjs +2 -1
- package/dist/rules/index.mjs.map +1 -1
- package/dist/rules/typescript-eslint-rules.mjs +1 -1
- package/dist/types/define-known-rules.d.mts +2 -2
- package/dist/types/define-known-rules.d.mts.map +1 -1
- package/dist/types/define-known-rules.mjs.map +1 -1
- package/dist/types/flat-config.d.mts.map +1 -1
- package/dist/types/rules/eslint-import-rules.d.mts +295 -336
- package/dist/types/rules/eslint-import-rules.d.mts.map +1 -1
- package/dist/types/rules/eslint-react-coding-style-rules.d.mts +148 -0
- package/dist/types/rules/eslint-react-coding-style-rules.d.mts.map +1 -0
- package/dist/types/rules/eslint-react-coding-style-rules.mjs +2 -0
- package/dist/types/rules/eslint-react-coding-style-rules.mjs.map +1 -0
- package/dist/types/rules/index.d.mts +1 -0
- package/dist/types/rules/index.d.mts.map +1 -1
- package/package.json +2 -5
- package/src/configs/plugins.mts +8 -3
- package/src/configs/react-base.mts +2 -0
- package/src/configs/typescript-without-rules.mts +4 -4
- package/src/configs/typescript.mts +8 -8
- package/src/entry-point.mts +2 -1
- package/src/plugins/index.mts +1 -0
- package/src/plugins/react-coding-style/README.md +36 -0
- package/src/plugins/react-coding-style/index.mts +1 -0
- package/src/plugins/react-coding-style/plugin.mts +6 -0
- package/src/plugins/react-coding-style/rules/ban-use-imperative-handle-hook.mts +31 -0
- package/src/plugins/react-coding-style/rules/ban-use-imperative-handle-hook.test.mts +40 -0
- package/src/plugins/react-coding-style/rules/component-name.mts +93 -0
- package/src/plugins/react-coding-style/rules/component-name.test.mts +72 -0
- package/src/plugins/react-coding-style/rules/component-var-type-annotation.mts +54 -0
- package/src/plugins/react-coding-style/rules/component-var-type-annotation.test.mts +62 -0
- package/src/plugins/react-coding-style/rules/import-style.mts +53 -0
- package/src/plugins/react-coding-style/rules/import-style.test.mts +63 -0
- package/src/plugins/react-coding-style/rules/index.mts +1 -0
- package/src/plugins/react-coding-style/rules/props-type-annotation-style.mts +59 -0
- package/src/plugins/react-coding-style/rules/props-type-annotation-style.test.mts +71 -0
- package/src/plugins/react-coding-style/rules/react-memo-props-argument-name.mts +70 -0
- package/src/plugins/react-coding-style/rules/react-memo-props-argument-name.test.mts +56 -0
- package/src/plugins/react-coding-style/rules/react-memo-type-parameter.mts +102 -0
- package/src/plugins/react-coding-style/rules/react-memo-type-parameter.test.mts +98 -0
- package/src/plugins/react-coding-style/rules/rules.mts +20 -0
- package/src/plugins/react-coding-style/rules/shared.mts +33 -0
- package/src/plugins/react-coding-style/rules/use-memo-hooks-style.mts +52 -0
- package/src/plugins/react-coding-style/rules/use-memo-hooks-style.test.mts +72 -0
- package/src/plugins/total-functions/rules/common.mts +1 -1
- package/src/plugins/total-functions/rules/fp-ts.mts +1 -1
- package/src/plugins/total-functions/rules/no-enums.mts +1 -1
- package/src/plugins/total-functions/rules/unsafe-assignment-rule.mts +1 -1
- package/src/rules/eslint-import-rules.mts +58 -55
- package/src/rules/eslint-react-coding-style-rules.mts +14 -0
- package/src/rules/eslint-rules.mts +0 -181
- package/src/rules/index.mts +1 -0
- package/src/rules/typescript-eslint-rules.mts +1 -1
- package/src/types/define-known-rules.mts +2 -0
- package/src/types/flat-config.mts +0 -1
- package/src/types/rules/eslint-import-rules.mts +305 -362
- package/src/types/rules/eslint-react-coding-style-rules.mts +166 -0
- package/src/types/rules/index.mts +1 -0
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ A comprehensive ESLint configuration package with strongly-typed rule definition
|
|
|
36
36
|
- [Rule Types](#rule-types)
|
|
37
37
|
- [Customization](#customization)
|
|
38
38
|
- [Override Specific Rules](#override-specific-rules)
|
|
39
|
-
- [Use
|
|
39
|
+
- [Use RulesOptions Types](#use-rulesoptions-types)
|
|
40
40
|
- [Target Specific Files](#target-specific-files)
|
|
41
41
|
- [Troubleshooting](#troubleshooting)
|
|
42
42
|
- [Common Issues](#common-issues)
|
|
@@ -49,7 +49,7 @@ A comprehensive ESLint configuration package with strongly-typed rule definition
|
|
|
49
49
|
|
|
50
50
|
## Features
|
|
51
51
|
|
|
52
|
-
- 🎯 **Type-Safe Configuration**: Fully typed ESLint rules and configurations for better IDE support
|
|
52
|
+
- 🎯 **Type-Safe Configuration**: Fully typed ESLint rules **and options** and configurations for better IDE support
|
|
53
53
|
- 📦 **Pre-configured Setups**: Ready-to-use configurations for TypeScript, React, Preact, and popular testing frameworks
|
|
54
54
|
- 📝 **Comprehensive Type Definitions**: Complete TypeScript types for all ESLint rules and options
|
|
55
55
|
- 🔄 **ESLint Flat Config Support**: Built for the modern ESLint flat configuration system
|
|
@@ -75,15 +75,17 @@ All required ESLint plugins and dependencies are automatically installed.
|
|
|
75
75
|
|
|
76
76
|
## Quick Start
|
|
77
77
|
|
|
78
|
-
Create an `eslint.config.js` file in your project root:
|
|
78
|
+
Create an `eslint.config.js` or `eslint.config.ts` file in your project root:
|
|
79
79
|
|
|
80
|
-
```
|
|
80
|
+
```tsx
|
|
81
81
|
import {
|
|
82
82
|
defineConfig,
|
|
83
|
+
defineKnownRules,
|
|
83
84
|
eslintConfigForTypeScript,
|
|
84
85
|
eslintConfigForVitest,
|
|
85
|
-
|
|
86
|
+
withDefaultOption,
|
|
86
87
|
} from 'eslint-config-typed';
|
|
88
|
+
|
|
87
89
|
// import * as path from 'node:path';
|
|
88
90
|
// import * as url from 'node:url';
|
|
89
91
|
|
|
@@ -110,17 +112,15 @@ export default defineConfig([
|
|
|
110
112
|
// You can override per-rule settings if necessary.
|
|
111
113
|
{
|
|
112
114
|
rules: defineKnownRules({
|
|
113
|
-
'@typescript-eslint/no-explicit-any': 'warn',
|
|
115
|
+
'@typescript-eslint/no-explicit-any': withDefaultOption('warn'),
|
|
114
116
|
'@typescript-eslint/prefer-readonly-parameter-types': 'off',
|
|
115
|
-
'react-hooks/exhaustive-deps': 'warn',
|
|
117
|
+
'react-hooks/exhaustive-deps': withDefaultOption('warn'),
|
|
116
118
|
'functional/no-let': [
|
|
117
119
|
'error',
|
|
118
120
|
{
|
|
119
121
|
allowInForLoopInit: true,
|
|
120
122
|
allowInFunctions: false,
|
|
121
|
-
ignoreIdentifierPattern:
|
|
122
|
-
(p) => p !== '^draft',
|
|
123
|
-
),
|
|
123
|
+
ignoreIdentifierPattern: ['^mut_', '^_mut_', '^#mut_'],
|
|
124
124
|
},
|
|
125
125
|
],
|
|
126
126
|
}),
|
|
@@ -151,14 +151,20 @@ npm run lint:fix
|
|
|
151
151
|
|
|
152
152
|
`defineConfig` wraps your flat configuration array so JavaScript config files get full IntelliSense without relying on JSDoc casts. It keeps literal types intact while returning the config unchanged at runtime.
|
|
153
153
|
|
|
154
|
-
```
|
|
155
|
-
import {
|
|
154
|
+
```tsx
|
|
155
|
+
import {
|
|
156
|
+
defineConfig,
|
|
157
|
+
defineKnownRules,
|
|
158
|
+
eslintConfigForTypeScript,
|
|
159
|
+
} from 'eslint-config-typed';
|
|
160
|
+
|
|
161
|
+
const thisDir = import.meta.dirname;
|
|
156
162
|
|
|
157
163
|
export default defineConfig([
|
|
158
164
|
...eslintConfigForTypeScript({
|
|
159
|
-
tsconfigRootDir:
|
|
165
|
+
tsconfigRootDir: thisDir,
|
|
160
166
|
tsconfigFileName: './tsconfig.json',
|
|
161
|
-
packageDirs: [
|
|
167
|
+
packageDirs: [thisDir],
|
|
162
168
|
}),
|
|
163
169
|
{
|
|
164
170
|
rules: defineKnownRules({
|
|
@@ -170,93 +176,195 @@ export default defineConfig([
|
|
|
170
176
|
|
|
171
177
|
This is equivalent to:
|
|
172
178
|
|
|
173
|
-
```
|
|
174
|
-
import {
|
|
179
|
+
```tsx
|
|
180
|
+
import {
|
|
181
|
+
defineKnownRules,
|
|
182
|
+
eslintConfigForTypeScript,
|
|
183
|
+
type FlatConfig,
|
|
184
|
+
} from 'eslint-config-typed';
|
|
185
|
+
|
|
186
|
+
const thisDir = import.meta.dirname;
|
|
175
187
|
|
|
176
|
-
/** @type {import('@typescript-eslint/utils/ts-eslint').FlatConfig[]} */
|
|
177
188
|
export default [
|
|
178
189
|
...eslintConfigForTypeScript({
|
|
179
|
-
tsconfigRootDir:
|
|
190
|
+
tsconfigRootDir: thisDir,
|
|
180
191
|
tsconfigFileName: './tsconfig.json',
|
|
181
|
-
packageDirs: [
|
|
192
|
+
packageDirs: [thisDir],
|
|
182
193
|
}),
|
|
183
194
|
{
|
|
184
195
|
rules: defineKnownRules({
|
|
185
196
|
// ...
|
|
186
197
|
}),
|
|
187
198
|
},
|
|
188
|
-
];
|
|
199
|
+
] satisfies readonly FlatConfig[];
|
|
189
200
|
```
|
|
190
201
|
|
|
191
202
|
### defineKnownRules utility
|
|
192
203
|
|
|
193
|
-
`defineKnownRules` is a helper designed for the `rules` field in ESLint flat configs. It keeps the returned object untouched while giving you type-safe rule names and option inference in editors. When you wrap your overrides with this function you can rely on:
|
|
204
|
+
`defineKnownRules` is a helper designed for the `rules` field in ESLint flat configs. It keeps the returned object untouched while giving you **type-safe rule names and option inference** in editors (like biome.json). When you wrap your overrides with this function you can rely on:
|
|
194
205
|
|
|
195
206
|
- autocomplete and early feedback for rule identifiers, eliminating typo-prone string literals;
|
|
196
207
|
- strongly typed options for every plugin rule that ships with `eslint-config-typed`, so you can discover valid properties without leaving your editor;
|
|
197
208
|
- a zero-cost runtime helper—because the object is returned as-is, it blends seamlessly into any flat config block.
|
|
198
209
|
|
|
210
|
+
```tsx
|
|
211
|
+
import {
|
|
212
|
+
defineKnownRules,
|
|
213
|
+
eslintConfigForTypeScript,
|
|
214
|
+
type FlatConfig,
|
|
215
|
+
} from 'eslint-config-typed';
|
|
216
|
+
|
|
217
|
+
const thisDir = import.meta.dirname;
|
|
218
|
+
|
|
219
|
+
export default [
|
|
220
|
+
...eslintConfigForTypeScript({
|
|
221
|
+
tsconfigRootDir: thisDir,
|
|
222
|
+
tsconfigFileName: './tsconfig.json',
|
|
223
|
+
packageDirs: [thisDir],
|
|
224
|
+
}),
|
|
225
|
+
{
|
|
226
|
+
rules: defineKnownRules({
|
|
227
|
+
// @ts-expect-error typo of rule name
|
|
228
|
+
'no-restricted-globalsSSSS': 'error',
|
|
229
|
+
// ~~~~~~~~~~~~~~~~~~~~~~~
|
|
230
|
+
}),
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
rules: defineKnownRules({
|
|
234
|
+
'no-unsafe-optional-chaining': [
|
|
235
|
+
'error',
|
|
236
|
+
// @ts-expect-error typo of an option key
|
|
237
|
+
{ disallowArithmeticOperatorsSSSSS: true },
|
|
238
|
+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
239
|
+
],
|
|
240
|
+
}),
|
|
241
|
+
},
|
|
242
|
+
] satisfies FlatConfig[];
|
|
243
|
+
```
|
|
244
|
+
|
|
199
245
|
### withDefaultOption utility
|
|
200
246
|
|
|
201
247
|
`withDefaultOption` is a companion helper that highlights rules which ship with option objects. It maps the familiar severity strings to the numeric values ESLint expects: `withDefaultOption('error')` returns `2`, and `withDefaultOption('warn')` returns `1`. Within `defineKnownRules`, rules that provide options require one of these helpers when you want to keep the defaults and only adjust severity. This convention visually distinguishes rules that contain options, reminding users that a rule has configurable options.
|
|
202
248
|
|
|
203
249
|
`defineKnownRules` also reserves `0` for deprecated rules. The resulting severity matrix looks like this:
|
|
204
250
|
|
|
205
|
-
| Rule type | Allowed severity values in `defineKnownRules`
|
|
206
|
-
| :------------------- |
|
|
207
|
-
| Deprecated rule | `0`
|
|
208
|
-
| Rule without options | `"off"
|
|
209
|
-
| Rule with options | `"off"
|
|
251
|
+
| Rule type | Allowed severity values in `defineKnownRules` |
|
|
252
|
+
| :------------------- | :-------------------------------------------- | ------ | -------- | ------- | ------------------- |
|
|
253
|
+
| Deprecated rule | `0` |
|
|
254
|
+
| Rule without options | `"off" | "warn" | "error"` |
|
|
255
|
+
| Rule with options | `"off" | 1 | 2 | ["warn" | "error", <option>]` |
|
|
256
|
+
|
|
257
|
+
```tsx
|
|
258
|
+
import {
|
|
259
|
+
defineKnownRules,
|
|
260
|
+
eslintConfigForTypeScript,
|
|
261
|
+
withDefaultOption,
|
|
262
|
+
type FlatConfig,
|
|
263
|
+
} from 'eslint-config-typed';
|
|
264
|
+
|
|
265
|
+
const thisDir = import.meta.dirname;
|
|
266
|
+
|
|
267
|
+
export default [
|
|
268
|
+
...eslintConfigForTypeScript({
|
|
269
|
+
tsconfigRootDir: thisDir,
|
|
270
|
+
tsconfigFileName: './tsconfig.json',
|
|
271
|
+
packageDirs: [thisDir],
|
|
272
|
+
}),
|
|
273
|
+
{
|
|
274
|
+
rules: defineKnownRules({
|
|
275
|
+
// @ts-expect-error Simply passing the string "error" to a rule with options is not allowed
|
|
276
|
+
'no-restricted-globals': 'error',
|
|
277
|
+
// ~~~~~~~~~~~~~~~~~~~~
|
|
278
|
+
// ^ Type Error! (Because "no-restricted-globals" has options)
|
|
279
|
+
// NOTE: In addition, some rules, such as "no-restricted-syntax" "and no-restricted-globals", have no effect unless you set the option.
|
|
280
|
+
|
|
281
|
+
// OK
|
|
282
|
+
'object-shorthand': withDefaultOption('error'),
|
|
283
|
+
|
|
284
|
+
// OK (options are set explicitly)
|
|
285
|
+
'no-unsafe-optional-chaining': [
|
|
286
|
+
'error',
|
|
287
|
+
{ disallowArithmeticOperators: true },
|
|
288
|
+
],
|
|
289
|
+
}),
|
|
290
|
+
},
|
|
291
|
+
] satisfies FlatConfig[];
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### TypeScript Configuration Files
|
|
295
|
+
|
|
296
|
+
You can also write your eslint config in `.ts` or `.mts` format, all you need to do is run `npm add -D jiti`.
|
|
297
|
+
|
|
298
|
+
```tsx
|
|
299
|
+
import {
|
|
300
|
+
eslintConfigForTypeScript,
|
|
301
|
+
eslintConfigForVitest,
|
|
302
|
+
type FlatConfig,
|
|
303
|
+
} from 'eslint-config-typed';
|
|
304
|
+
|
|
305
|
+
const thisDir = import.meta.dirname;
|
|
306
|
+
|
|
307
|
+
export default [
|
|
308
|
+
...eslintConfigForTypeScript({
|
|
309
|
+
tsconfigRootDir: thisDir,
|
|
310
|
+
tsconfigFileName: './tsconfig.json',
|
|
311
|
+
packageDirs: [thisDir],
|
|
312
|
+
}),
|
|
313
|
+
eslintConfigForVitest(),
|
|
314
|
+
] satisfies FlatConfig[];
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
For details, see <https://eslint.org/docs/latest/use/configure/configuration-files#typescript-configuration-files>.
|
|
210
318
|
|
|
211
319
|
## Configuration Examples
|
|
212
320
|
|
|
213
321
|
### TypeScript + React Project
|
|
214
322
|
|
|
215
|
-
```
|
|
323
|
+
```tsx
|
|
216
324
|
import {
|
|
217
|
-
defineConfig,
|
|
218
|
-
eslintConfigForTypeScript,
|
|
219
|
-
eslintConfigForReact,
|
|
220
|
-
eslintConfigForNodeJs,
|
|
221
325
|
defineKnownRules,
|
|
326
|
+
eslintConfigForNodeJs,
|
|
327
|
+
eslintConfigForReact,
|
|
328
|
+
eslintConfigForTypeScript,
|
|
329
|
+
type FlatConfig,
|
|
222
330
|
} from 'eslint-config-typed';
|
|
223
331
|
|
|
224
332
|
const thisDir = import.meta.dirname;
|
|
225
333
|
|
|
226
|
-
export default
|
|
227
|
-
{ ignores: ['**/dist/**', '**/build/**', '**/.next/**'] },
|
|
334
|
+
export default [
|
|
335
|
+
{ ignores: ['**/dist/**', '**/build/**', '**/.next/**', 'public/**'] },
|
|
228
336
|
...eslintConfigForTypeScript({
|
|
229
337
|
tsconfigRootDir: thisDir,
|
|
230
338
|
tsconfigFileName: './tsconfig.json',
|
|
231
339
|
packageDirs: [thisDir],
|
|
232
340
|
}),
|
|
233
|
-
eslintConfigForReact(['src/**']),
|
|
341
|
+
...eslintConfigForReact(['src/**']),
|
|
234
342
|
eslintConfigForNodeJs(['scripts/**', 'configs/**']),
|
|
235
343
|
{
|
|
236
344
|
files: ['scripts/**', 'configs/**'],
|
|
237
345
|
rules: defineKnownRules({
|
|
238
346
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
239
347
|
'no-await-in-loop': 'off',
|
|
240
|
-
'import/no-unassigned-import': 'off',
|
|
241
|
-
'import/no-internal-modules': 'off',
|
|
242
|
-
'import/no-default-export': 'off',
|
|
243
|
-
'import/no-extraneous-dependencies': 'off',
|
|
348
|
+
'import-x/no-unassigned-import': 'off',
|
|
349
|
+
'import-x/no-internal-modules': 'off',
|
|
350
|
+
'import-x/no-default-export': 'off',
|
|
351
|
+
'import-x/no-extraneous-dependencies': 'off',
|
|
244
352
|
}),
|
|
245
353
|
},
|
|
246
|
-
]
|
|
354
|
+
] satisfies FlatConfig[];
|
|
247
355
|
```
|
|
248
356
|
|
|
249
357
|
### Node.js TypeScript Project
|
|
250
358
|
|
|
251
|
-
```
|
|
359
|
+
```tsx
|
|
252
360
|
import {
|
|
253
|
-
defineConfig,
|
|
254
|
-
eslintConfigForTypeScript,
|
|
255
|
-
eslintConfigForNodeJs,
|
|
256
361
|
defineKnownRules,
|
|
362
|
+
eslintConfigForNodeJs,
|
|
363
|
+
eslintConfigForTypeScript,
|
|
364
|
+
type FlatConfig,
|
|
257
365
|
} from 'eslint-config-typed';
|
|
258
366
|
|
|
259
|
-
export default
|
|
367
|
+
export default [
|
|
260
368
|
{ ignores: ['**/dist/**', '**/node_modules/**'] },
|
|
261
369
|
...eslintConfigForTypeScript({
|
|
262
370
|
tsconfigRootDir: import.meta.dirname,
|
|
@@ -268,25 +376,23 @@ export default defineConfig([
|
|
|
268
376
|
rules: defineKnownRules({
|
|
269
377
|
// Allow console in Node.js
|
|
270
378
|
'no-console': 'off',
|
|
271
|
-
// Allow process.env access
|
|
272
|
-
'no-process-env': 'off',
|
|
273
379
|
}),
|
|
274
380
|
},
|
|
275
|
-
]
|
|
381
|
+
] satisfies FlatConfig[];
|
|
276
382
|
```
|
|
277
383
|
|
|
278
384
|
### React + Testing Libraries
|
|
279
385
|
|
|
280
|
-
```
|
|
386
|
+
```tsx
|
|
281
387
|
import {
|
|
282
|
-
defineConfig,
|
|
283
|
-
eslintConfigForTypeScript,
|
|
284
388
|
eslintConfigForReact,
|
|
285
|
-
eslintConfigForVitest,
|
|
286
389
|
eslintConfigForTestingLibrary,
|
|
390
|
+
eslintConfigForTypeScript,
|
|
391
|
+
eslintConfigForVitest,
|
|
392
|
+
type FlatConfig,
|
|
287
393
|
} from 'eslint-config-typed';
|
|
288
394
|
|
|
289
|
-
export default
|
|
395
|
+
export default [
|
|
290
396
|
{ ignores: ['**/dist/**', '**/coverage/**'] },
|
|
291
397
|
...eslintConfigForTypeScript({
|
|
292
398
|
tsconfigRootDir: import.meta.dirname,
|
|
@@ -296,7 +402,7 @@ export default defineConfig([
|
|
|
296
402
|
...eslintConfigForReact(),
|
|
297
403
|
eslintConfigForVitest(),
|
|
298
404
|
eslintConfigForTestingLibrary(),
|
|
299
|
-
]
|
|
405
|
+
] satisfies FlatConfig[];
|
|
300
406
|
```
|
|
301
407
|
|
|
302
408
|
## VS Code Integration
|
|
@@ -310,36 +416,13 @@ Add the following to `.vscode/settings.json` for proper ESLint integration:
|
|
|
310
416
|
"mode": "auto"
|
|
311
417
|
}
|
|
312
418
|
],
|
|
313
|
-
"eslint.experimental.useFlatConfig": true
|
|
314
|
-
"editor.codeActionsOnSave": {
|
|
315
|
-
|
|
316
|
-
}
|
|
419
|
+
"eslint.experimental.useFlatConfig": true
|
|
420
|
+
// "editor.codeActionsOnSave": {
|
|
421
|
+
// "source.fixAll.eslint": "explicit"
|
|
422
|
+
// }
|
|
317
423
|
}
|
|
318
424
|
```
|
|
319
425
|
|
|
320
|
-
## TypeScript Configuration Files
|
|
321
|
-
|
|
322
|
-
You can also write your eslint config in `.ts` or `.mts` format, all you need to do is run `npm add -D jiti`.
|
|
323
|
-
|
|
324
|
-
```ts
|
|
325
|
-
import {
|
|
326
|
-
eslintConfigForTypeScript,
|
|
327
|
-
eslintConfigForVitest,
|
|
328
|
-
type FlatConfig,
|
|
329
|
-
} from 'eslint-config-typed';
|
|
330
|
-
|
|
331
|
-
export default [
|
|
332
|
-
...eslintConfigForTypeScript({
|
|
333
|
-
tsconfigRootDir: thisDir,
|
|
334
|
-
tsconfigFileName: './tsconfig.json',
|
|
335
|
-
packageDirs: [thisDir],
|
|
336
|
-
}),
|
|
337
|
-
eslintConfigForVitest(),
|
|
338
|
-
] satisfies FlatConfig[];
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
For details, see <https://eslint.org/docs/latest/use/configure/configuration-files#typescript-configuration-files>.
|
|
342
|
-
|
|
343
426
|
## Included plugins
|
|
344
427
|
|
|
345
428
|
- @typescript-eslint/eslint-plugin
|
|
@@ -351,7 +434,7 @@ For details, see <https://eslint.org/docs/latest/use/configure/configuration-fil
|
|
|
351
434
|
- eslint-plugin-sort-destructure-keys
|
|
352
435
|
- eslint-plugin-security
|
|
353
436
|
- eslint-plugin-promise
|
|
354
|
-
- eslint-plugin-import
|
|
437
|
+
- eslint-plugin-import-x
|
|
355
438
|
- eslint-plugin-strict-dependencies
|
|
356
439
|
- eslint-plugin-tree-shakable (Reimplemented in this repository to support flat config)
|
|
357
440
|
- eslint-plugin-react
|
|
@@ -370,7 +453,7 @@ For details, see <https://eslint.org/docs/latest/use/configure/configuration-fil
|
|
|
370
453
|
|
|
371
454
|
### Configuration Functions
|
|
372
455
|
|
|
373
|
-
These functions return arrays of ESLint flat
|
|
456
|
+
These functions return (arrays of) ESLint flat configuration(s):
|
|
374
457
|
|
|
375
458
|
#### Base Configurations
|
|
376
459
|
|
|
@@ -385,7 +468,7 @@ These functions return arrays of ESLint flat configurations:
|
|
|
385
468
|
|
|
386
469
|
- **`eslintConfigForReact(options?)`** - React configuration with hooks and JSX rules
|
|
387
470
|
- `eslintConfigForBrowser` is included in this configuration
|
|
388
|
-
- **`eslintConfigForPreact(options?)`** - Preact
|
|
471
|
+
- **`eslintConfigForPreact(options?)`** - Preact (lighter React alternative) configuration
|
|
389
472
|
- `eslintConfigForBrowser` is included in this configuration
|
|
390
473
|
- **`eslintConfigForVitest(options?)`** - Vitest testing framework configuration
|
|
391
474
|
- **`eslintConfigForJest(options?)`** - Jest testing framework configuration
|
|
@@ -401,31 +484,32 @@ These functions return arrays of ESLint flat configurations:
|
|
|
401
484
|
|
|
402
485
|
Pre-configured rule sets that can be imported and customized:
|
|
403
486
|
|
|
404
|
-
| Rule set | Plugin name | Description
|
|
405
|
-
| :----------------------------------------- | :------------------------------------- |
|
|
406
|
-
| **`eslintRules`** | (eslint) | Core ESLint rules
|
|
407
|
-
| **`typescriptEslintRules`** | `@typescript-eslint/eslint-plugin` | TypeScript-specific ESLint rules
|
|
408
|
-
| **`eslintFunctionalRules`** | `eslint-plugin-functional` | Functional programming style rules
|
|
409
|
-
| **`eslintTotalFunctionsRules`** | `eslint-plugin-total-functions` | Functional programming style rules
|
|
410
|
-
| **`eslintUnicornRules`** | `eslint-plugin-unicorn` | Unicorn plugin rules for better code
|
|
411
|
-
| **`eslintArrayFuncRules`** | `eslint-plugin-array-func` | Array function preference rules
|
|
412
|
-
| **`eslintPreferArrowFunctionRules`** | `eslint-plugin-prefer-arrow-functions` | Arrow function preference rules
|
|
413
|
-
| **`eslintPluginSortDestructureKeysRules`** | `eslint-plugin-sort-destructure-keys` | Object destructuring rules
|
|
414
|
-
| **`eslintPromiseRules`** | `eslint-plugin-promise` | Promise handling rules
|
|
415
|
-
| **`eslintImportsRules`** | `eslint-plugin-import`
|
|
416
|
-
| **`eslintSecurityRules`** | `eslint-plugin-security` | Security best practices
|
|
417
|
-
| **`eslintTreeShakableRules`** | `eslint-plugin-tree-shakable` | Tree-shaking optimization rules
|
|
418
|
-
| **`eslintReactRules`** | `eslint-plugin-react` | React-specific rules
|
|
419
|
-
| **`eslintReactHooksRules`** | `eslint-plugin-react-hooks` | React Hooks rules
|
|
420
|
-
| **`eslintReactPerfRules`** | `eslint-plugin-react-perf` | React performance optimization rules
|
|
421
|
-
| **`eslintReactRefreshRules`** | `eslint-plugin-react-refresh` | React Refresh (HMR) rules
|
|
422
|
-
| **`
|
|
423
|
-
| **`
|
|
424
|
-
| **`
|
|
425
|
-
| **`
|
|
426
|
-
| **`
|
|
427
|
-
| **`
|
|
428
|
-
| **`
|
|
487
|
+
| Rule set | Plugin name | Description |
|
|
488
|
+
| :----------------------------------------- | :------------------------------------- | :-------------------------------------- |
|
|
489
|
+
| **`eslintRules`** | (eslint) | Core ESLint rules |
|
|
490
|
+
| **`typescriptEslintRules`** | `@typescript-eslint/eslint-plugin` | TypeScript-specific ESLint rules |
|
|
491
|
+
| **`eslintFunctionalRules`** | `eslint-plugin-functional` | Functional programming style rules |
|
|
492
|
+
| **`eslintTotalFunctionsRules`** | `eslint-plugin-total-functions` | Functional programming style rules |
|
|
493
|
+
| **`eslintUnicornRules`** | `eslint-plugin-unicorn` | Unicorn plugin rules for better code |
|
|
494
|
+
| **`eslintArrayFuncRules`** | `eslint-plugin-array-func` | Array function preference rules |
|
|
495
|
+
| **`eslintPreferArrowFunctionRules`** | `eslint-plugin-prefer-arrow-functions` | Arrow function preference rules |
|
|
496
|
+
| **`eslintPluginSortDestructureKeysRules`** | `eslint-plugin-sort-destructure-keys` | Object destructuring rules |
|
|
497
|
+
| **`eslintPromiseRules`** | `eslint-plugin-promise` | Promise handling rules |
|
|
498
|
+
| **`eslintImportsRules`** | `eslint-plugin-import-x` | Import/export rules |
|
|
499
|
+
| **`eslintSecurityRules`** | `eslint-plugin-security` | Security best practices |
|
|
500
|
+
| **`eslintTreeShakableRules`** | `eslint-plugin-tree-shakable` | Tree-shaking optimization rules |
|
|
501
|
+
| **`eslintReactRules`** | `eslint-plugin-react` | React-specific rules |
|
|
502
|
+
| **`eslintReactHooksRules`** | `eslint-plugin-react-hooks` | React Hooks rules |
|
|
503
|
+
| **`eslintReactPerfRules`** | `eslint-plugin-react-perf` | React performance optimization rules |
|
|
504
|
+
| **`eslintReactRefreshRules`** | `eslint-plugin-react-refresh` | React Refresh (HMR) rules |
|
|
505
|
+
| **`eslintReactCodingStyleRules`** | `eslint-plugin-react-coding-style` | Opinionated React component style rules |
|
|
506
|
+
| **`eslintJsxA11yRules`** | `eslint-plugin-jsx-a11y` | Accessibility rules for JSX |
|
|
507
|
+
| **`eslintVitestRules`** | `eslint-plugin-vitest` | Vitest-specific rules |
|
|
508
|
+
| **`eslintJestRules`** | `eslint-plugin-jest` | Jest-specific rules |
|
|
509
|
+
| **`eslintTestingLibraryRules`** | `eslint-plugin-testing-library` | Testing Library rules |
|
|
510
|
+
| **`eslintPlaywrightRules`** | `eslint-plugin-playwright` | Playwright-specific rules |
|
|
511
|
+
| **`eslintCypressRules`** | `eslint-plugin-cypress` | Cypress-specific rules |
|
|
512
|
+
| **`eslintPluginRules`** | `eslint-plugin-eslint-plugin` | eslint-plugin development rules |
|
|
429
513
|
|
|
430
514
|
### Exported Pre-configured Rule Options
|
|
431
515
|
|
|
@@ -434,7 +518,6 @@ Pre-configured rule sets that can be imported and customized:
|
|
|
434
518
|
| **`restrictedGlobals`** | `no-restricted-globals` | Array of restricted global variables |
|
|
435
519
|
| **`restrictedGlobalsForBrowser`** | `no-restricted-globals` | Browser-environment-specific restricted globals |
|
|
436
520
|
| **`restrictedSyntax`** | `no-restricted-syntax` | Disallows the `in` operator, `Object.prototype.hasOwnProperty.call` (suggests using `Object.hasOwn`), and `new Array(*)` syntax (suggests using `Array.from`) |
|
|
437
|
-
| **`restrictedSyntaxForReact`** | `no-restricted-syntax` | Rule set to restrict React component styling |
|
|
438
521
|
|
|
439
522
|
You can find other pre-configured rule options by traversing the pre-defined rules object like this:
|
|
440
523
|
|
|
@@ -449,16 +532,23 @@ The shape of the rule option varies depending on the rule, so please check the c
|
|
|
449
532
|
- `eslint-plugin-total-functions` with support for Flat Config
|
|
450
533
|
- **`eslintPluginTreeShakable`**
|
|
451
534
|
- `eslint-plugin-tree-shakable` with support for Flat Config
|
|
535
|
+
- **`eslintPluginReactCodingStyle`**
|
|
536
|
+
- Custom ESLint plugin that codifies this repository's React memo component conventions (namespace imports, `React.memo<Props>`, arrow props naming, etc.). See [`src/plugins/react-coding-style/README.md`](src/plugins/react-coding-style/README.md) for the rationale and examples.
|
|
537
|
+
- Provides rules such as `react-coding-style/import-style`, `react-coding-style/component-var-type-annotation`, `react-coding-style/react-memo-type-parameter`, `react-coding-style/react-memo-props-argument-name`, `react-coding-style/props-type-annotation-style`, and `react-coding-style/react-hooks-definition-style`.
|
|
452
538
|
- **`eslintPluginCustom`** - Custom ESLint plugin with additional rules
|
|
453
539
|
- Currently, this plugin only provides the `custom/no-restricted-syntax` rule (which duplicates ESLint's `no-restricted-syntax` rule).
|
|
454
540
|
- Can be used to set the error level to `error` or `warn` as needed.
|
|
455
541
|
|
|
456
542
|
Example:
|
|
457
543
|
|
|
458
|
-
```
|
|
459
|
-
import {
|
|
544
|
+
```tsx
|
|
545
|
+
import {
|
|
546
|
+
defineKnownRules,
|
|
547
|
+
eslintRules,
|
|
548
|
+
type FlatConfig,
|
|
549
|
+
} from 'eslint-config-typed';
|
|
460
550
|
|
|
461
|
-
export default
|
|
551
|
+
export default [
|
|
462
552
|
// ...
|
|
463
553
|
{
|
|
464
554
|
rules: defineKnownRules({
|
|
@@ -478,7 +568,7 @@ export default defineConfig([
|
|
|
478
568
|
],
|
|
479
569
|
}),
|
|
480
570
|
},
|
|
481
|
-
]
|
|
571
|
+
] satisfies FlatConfig[];
|
|
482
572
|
```
|
|
483
573
|
|
|
484
574
|
### Type Definitions
|
|
@@ -488,9 +578,13 @@ All rules and configurations come with complete TypeScript type definitions:
|
|
|
488
578
|
#### Core Types
|
|
489
579
|
|
|
490
580
|
- **`FlatConfig`** - ESLint flat configuration type
|
|
581
|
+
- `= DeepReadonly<import('@typescript-eslint/utils/ts-eslint').FlatConfig>`
|
|
491
582
|
- **`ESLintPlugin`** - ESLint plugin type
|
|
583
|
+
- `= DeepReadonly<import('@typescript-eslint/utils/ts-eslint').FlatConfig.Plugin>`
|
|
492
584
|
- **`Rule`** - ESLint rule definition type
|
|
585
|
+
- `= DeepReadonly<import('@eslint/core').RuleDefinition>`
|
|
493
586
|
- **`Rules`** - Collection of rules type
|
|
587
|
+
- `= Readonly<Record<string, Rule>>`
|
|
494
588
|
|
|
495
589
|
#### Rule Types
|
|
496
590
|
|
|
@@ -533,15 +627,27 @@ The pre-configured rules of `eslint-config-typed` are opinionated settings that
|
|
|
533
627
|
|
|
534
628
|
You can override any rule by adding a configuration object after the preset configurations:
|
|
535
629
|
|
|
536
|
-
```
|
|
537
|
-
import {
|
|
630
|
+
```tsx
|
|
631
|
+
import {
|
|
632
|
+
defineKnownRules,
|
|
633
|
+
eslintConfigForTypeScript,
|
|
634
|
+
type FlatConfig,
|
|
635
|
+
typescriptEslintRules,
|
|
636
|
+
withDefaultOption,
|
|
637
|
+
} from 'eslint-config-typed';
|
|
538
638
|
|
|
539
|
-
|
|
540
|
-
|
|
639
|
+
const thisDir = import.meta.dirname;
|
|
640
|
+
|
|
641
|
+
export default [
|
|
642
|
+
...eslintConfigForTypeScript({
|
|
643
|
+
tsconfigRootDir: thisDir,
|
|
644
|
+
tsconfigFileName: './tsconfig.json',
|
|
645
|
+
packageDirs: [thisDir],
|
|
646
|
+
}),
|
|
541
647
|
{
|
|
542
648
|
rules: defineKnownRules({
|
|
543
649
|
// Downgrade to warning (Option settings are inherited)
|
|
544
|
-
'@typescript-eslint/no-explicit-any': 'warn',
|
|
650
|
+
'@typescript-eslint/no-explicit-any': withDefaultOption('warn'),
|
|
545
651
|
// Disable a rule
|
|
546
652
|
'@typescript-eslint/prefer-readonly-parameter-types': 'off',
|
|
547
653
|
// Configure with options
|
|
@@ -567,19 +673,18 @@ export default defineConfig([
|
|
|
567
673
|
],
|
|
568
674
|
}),
|
|
569
675
|
},
|
|
570
|
-
]
|
|
676
|
+
] satisfies FlatConfig[];
|
|
571
677
|
```
|
|
572
678
|
|
|
573
|
-
### Use
|
|
679
|
+
### Use RulesOptions Types
|
|
574
680
|
|
|
575
681
|
Leverage TypeScript for type-safe rule configuration:
|
|
576
682
|
|
|
577
|
-
```
|
|
683
|
+
```tsx
|
|
578
684
|
// configs/restricted-syntax-defs.mjs
|
|
579
685
|
|
|
580
|
-
import { eslintRules } from 'eslint-config-typed';
|
|
686
|
+
import { eslintRules, type EslintRulesOption } from 'eslint-config-typed';
|
|
581
687
|
|
|
582
|
-
/** @type {import("eslint-config-typed").EslintRulesOption["no-restricted-syntax"]} */
|
|
583
688
|
export const restrictedSyntax = [
|
|
584
689
|
...eslintRules['no-restricted-syntax'].slice(1),
|
|
585
690
|
{
|
|
@@ -589,31 +694,54 @@ export const restrictedSyntax = [
|
|
|
589
694
|
message:
|
|
590
695
|
'The variable type T should be annotated as `React.useMemo<T>` or `const v: T = React.useMemo(...)`.',
|
|
591
696
|
},
|
|
592
|
-
];
|
|
697
|
+
] satisfies EslintRulesOption['no-restricted-syntax'];
|
|
593
698
|
```
|
|
594
699
|
|
|
595
|
-
```
|
|
596
|
-
// eslint.config.
|
|
700
|
+
```tsx
|
|
701
|
+
// eslint.config.mts
|
|
702
|
+
|
|
703
|
+
import {
|
|
704
|
+
defineKnownRules,
|
|
705
|
+
eslintConfigForTypeScript,
|
|
706
|
+
type FlatConfig,
|
|
707
|
+
} from 'eslint-config-typed';
|
|
708
|
+
import { restrictedSyntax } from './restricted-syntax-defs.mjs';
|
|
597
709
|
|
|
598
|
-
|
|
710
|
+
const thisDir = import.meta.dirname;
|
|
599
711
|
|
|
600
|
-
export default
|
|
601
|
-
...eslintConfigForTypeScript(
|
|
712
|
+
export default [
|
|
713
|
+
...eslintConfigForTypeScript({
|
|
714
|
+
tsconfigRootDir: thisDir,
|
|
715
|
+
tsconfigFileName: './tsconfig.json',
|
|
716
|
+
packageDirs: [thisDir],
|
|
717
|
+
}),
|
|
602
718
|
{
|
|
603
719
|
rules: defineKnownRules({
|
|
604
|
-
'no-restricted-syntax': ['error', restrictedSyntax],
|
|
720
|
+
'no-restricted-syntax': ['error', ...restrictedSyntax],
|
|
605
721
|
}),
|
|
606
722
|
},
|
|
607
|
-
]
|
|
723
|
+
] satisfies readonly FlatConfig[];
|
|
608
724
|
```
|
|
609
725
|
|
|
610
726
|
### Target Specific Files
|
|
611
727
|
|
|
612
728
|
Apply different rules to different file patterns:
|
|
613
729
|
|
|
614
|
-
```
|
|
615
|
-
|
|
616
|
-
|
|
730
|
+
```tsx
|
|
731
|
+
import {
|
|
732
|
+
defineKnownRules,
|
|
733
|
+
eslintConfigForTypeScript,
|
|
734
|
+
type FlatConfig,
|
|
735
|
+
} from 'eslint-config-typed';
|
|
736
|
+
|
|
737
|
+
const thisDir = import.meta.dirname;
|
|
738
|
+
|
|
739
|
+
export default [
|
|
740
|
+
...eslintConfigForTypeScript({
|
|
741
|
+
tsconfigRootDir: thisDir,
|
|
742
|
+
tsconfigFileName: './tsconfig.json',
|
|
743
|
+
packageDirs: [thisDir],
|
|
744
|
+
}),
|
|
617
745
|
{
|
|
618
746
|
files: ['**/*.test.ts', '**/*.spec.ts'],
|
|
619
747
|
rules: defineKnownRules({
|
|
@@ -628,10 +756,10 @@ export default defineConfig([
|
|
|
628
756
|
rules: defineKnownRules({
|
|
629
757
|
// Allow console in scripts
|
|
630
758
|
'no-await-in-loop': 'off',
|
|
631
|
-
'import/no-unassigned-import': 'off',
|
|
759
|
+
'import-x/no-unassigned-import': 'off',
|
|
632
760
|
}),
|
|
633
761
|
},
|
|
634
|
-
]
|
|
762
|
+
] satisfies FlatConfig[];
|
|
635
763
|
```
|
|
636
764
|
|
|
637
765
|
## Troubleshooting
|
|
@@ -642,33 +770,41 @@ export default defineConfig([
|
|
|
642
770
|
|
|
643
771
|
Ensure the paths are correct:
|
|
644
772
|
|
|
645
|
-
```
|
|
773
|
+
```tsx
|
|
774
|
+
import {
|
|
775
|
+
eslintConfigForTypeScript,
|
|
776
|
+
type FlatConfig,
|
|
777
|
+
} from 'eslint-config-typed';
|
|
778
|
+
|
|
646
779
|
const thisDir = import.meta.dirname;
|
|
647
780
|
|
|
648
|
-
export default
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
}),
|
|
654
|
-
]);
|
|
781
|
+
export default eslintConfigForTypeScript({
|
|
782
|
+
tsconfigRootDir: thisDir, // Must be absolute path
|
|
783
|
+
tsconfigFileName: './tsconfig.json', // Relative to tsconfigRootDir
|
|
784
|
+
packageDirs: [thisDir],
|
|
785
|
+
}) satisfies readonly FlatConfig[];
|
|
655
786
|
```
|
|
656
787
|
|
|
657
788
|
#### 2. Import resolution errors
|
|
658
789
|
|
|
659
790
|
The `packageDirs` option helps ESLint resolve imports correctly in monorepos:
|
|
660
791
|
|
|
661
|
-
```
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
792
|
+
```tsx
|
|
793
|
+
import {
|
|
794
|
+
eslintConfigForTypeScript,
|
|
795
|
+
type FlatConfig,
|
|
796
|
+
} from 'eslint-config-typed';
|
|
797
|
+
|
|
798
|
+
const thisDir = import.meta.dirname;
|
|
799
|
+
|
|
800
|
+
export default eslintConfigForTypeScript({
|
|
801
|
+
tsconfigRootDir: thisDir,
|
|
802
|
+
tsconfigFileName: './tsconfig.json',
|
|
803
|
+
packageDirs: [
|
|
804
|
+
path.resolve(thisDir, '../../..'), // Monorepo root
|
|
805
|
+
thisDir, // Current package
|
|
806
|
+
],
|
|
807
|
+
}) satisfies readonly FlatConfig[];
|
|
672
808
|
```
|
|
673
809
|
|
|
674
810
|
#### 3. Performance issues
|
|
@@ -682,9 +818,36 @@ For large projects, consider:
|
|
|
682
818
|
- Running ESLint with `--cache` flag
|
|
683
819
|
- Limiting the scope of type-aware rules
|
|
684
820
|
|
|
821
|
+
#### 4. How to Use import-x/no-unused-modules
|
|
822
|
+
|
|
823
|
+
[`import-x/no-unused-modules`](https://github.com/un-ts/eslint-plugin-import-x/blob/v4.16.1/docs/rules/no-unused-modules.md) reports exported values that are never imported anywhere else. The rule still relies on ESLint’s classic configuration loader to discover ignore patterns, so a flat-config-only setup is not enough. For this to work, you need to place a `.eslintrc.cjs` file along with `eslint.config.mts`.
|
|
824
|
+
|
|
825
|
+
```cjs
|
|
826
|
+
// .eslintrc.cjs
|
|
827
|
+
module.exports = {
|
|
828
|
+
ignorePatterns: ['**/node_modules/**', 'dist', '.eslintrc.cjs'],
|
|
829
|
+
};
|
|
830
|
+
```
|
|
831
|
+
|
|
832
|
+
The flat config then enables the rule for our source tree and marks the public federation module as an allowed unused export:
|
|
833
|
+
|
|
834
|
+
```ts
|
|
835
|
+
// eslint.config.mts (excerpt)
|
|
836
|
+
{
|
|
837
|
+
files: ['src/**'],
|
|
838
|
+
rules: defineKnownRules({
|
|
839
|
+
'import-x/no-unused-modules': [
|
|
840
|
+
'error',
|
|
841
|
+
{ unusedExports: true, ignoreExports: ['src/entry-point.mts'] },
|
|
842
|
+
],
|
|
843
|
+
}),
|
|
844
|
+
},
|
|
845
|
+
```
|
|
846
|
+
|
|
847
|
+
With this configuration, you can run eslint and receive actionable diagnostic information when exports are no longer referenced. If you implement a library, add the file paths that define the variables, types, etc. that your library exports to the `ignoreExports` array so that the rule does not flag intentionally re-exported surfaces.
|
|
848
|
+
|
|
685
849
|
### Known Limitations
|
|
686
850
|
|
|
687
|
-
- The `import/no-unused-modules` rule does not function properly with Native ESM
|
|
688
851
|
- Some type-aware rules may have performance impacts on very large codebases
|
|
689
852
|
- Flat config requires ESLint 9.0+ and may not be compatible with older tools
|
|
690
853
|
|