eslint-config-typed 3.0.0 β 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 +291 -131
- package/dist/configs/plugins.d.mts +1 -1
- package/dist/configs/plugins.d.mts.map +1 -1
- package/dist/configs/plugins.mjs +3 -2
- package/dist/configs/plugins.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/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 +1 -1
- package/dist/rules/eslint-react-coding-style-rules.d.mts.map +1 -1
- package/dist/rules/eslint-react-coding-style-rules.mjs +2 -1
- package/dist/rules/eslint-react-coding-style-rules.mjs.map +1 -1
- package/dist/rules/typescript-eslint-rules.mjs +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/package.json +3 -2
- package/src/configs/plugins.mts +5 -3
- package/src/configs/typescript-without-rules.mts +4 -4
- package/src/configs/typescript.mts +8 -8
- 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 +3 -1
- package/src/rules/typescript-eslint-rules.mts +1 -1
- package/src/types/flat-config.mts +0 -1
- package/src/types/rules/eslint-import-rules.mts +305 -362
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
|
|
@@ -412,7 +495,7 @@ Pre-configured rule sets that can be imported and customized:
|
|
|
412
495
|
| **`eslintPreferArrowFunctionRules`** | `eslint-plugin-prefer-arrow-functions` | Arrow function preference rules |
|
|
413
496
|
| **`eslintPluginSortDestructureKeysRules`** | `eslint-plugin-sort-destructure-keys` | Object destructuring rules |
|
|
414
497
|
| **`eslintPromiseRules`** | `eslint-plugin-promise` | Promise handling rules |
|
|
415
|
-
| **`eslintImportsRules`** | `eslint-plugin-import`
|
|
498
|
+
| **`eslintImportsRules`** | `eslint-plugin-import-x` | Import/export rules |
|
|
416
499
|
| **`eslintSecurityRules`** | `eslint-plugin-security` | Security best practices |
|
|
417
500
|
| **`eslintTreeShakableRules`** | `eslint-plugin-tree-shakable` | Tree-shaking optimization rules |
|
|
418
501
|
| **`eslintReactRules`** | `eslint-plugin-react` | React-specific rules |
|
|
@@ -458,10 +541,14 @@ The shape of the rule option varies depending on the rule, so please check the c
|
|
|
458
541
|
|
|
459
542
|
Example:
|
|
460
543
|
|
|
461
|
-
```
|
|
462
|
-
import {
|
|
544
|
+
```tsx
|
|
545
|
+
import {
|
|
546
|
+
defineKnownRules,
|
|
547
|
+
eslintRules,
|
|
548
|
+
type FlatConfig,
|
|
549
|
+
} from 'eslint-config-typed';
|
|
463
550
|
|
|
464
|
-
export default
|
|
551
|
+
export default [
|
|
465
552
|
// ...
|
|
466
553
|
{
|
|
467
554
|
rules: defineKnownRules({
|
|
@@ -481,7 +568,7 @@ export default defineConfig([
|
|
|
481
568
|
],
|
|
482
569
|
}),
|
|
483
570
|
},
|
|
484
|
-
]
|
|
571
|
+
] satisfies FlatConfig[];
|
|
485
572
|
```
|
|
486
573
|
|
|
487
574
|
### Type Definitions
|
|
@@ -491,9 +578,13 @@ All rules and configurations come with complete TypeScript type definitions:
|
|
|
491
578
|
#### Core Types
|
|
492
579
|
|
|
493
580
|
- **`FlatConfig`** - ESLint flat configuration type
|
|
581
|
+
- `= DeepReadonly<import('@typescript-eslint/utils/ts-eslint').FlatConfig>`
|
|
494
582
|
- **`ESLintPlugin`** - ESLint plugin type
|
|
583
|
+
- `= DeepReadonly<import('@typescript-eslint/utils/ts-eslint').FlatConfig.Plugin>`
|
|
495
584
|
- **`Rule`** - ESLint rule definition type
|
|
585
|
+
- `= DeepReadonly<import('@eslint/core').RuleDefinition>`
|
|
496
586
|
- **`Rules`** - Collection of rules type
|
|
587
|
+
- `= Readonly<Record<string, Rule>>`
|
|
497
588
|
|
|
498
589
|
#### Rule Types
|
|
499
590
|
|
|
@@ -536,15 +627,27 @@ The pre-configured rules of `eslint-config-typed` are opinionated settings that
|
|
|
536
627
|
|
|
537
628
|
You can override any rule by adding a configuration object after the preset configurations:
|
|
538
629
|
|
|
539
|
-
```
|
|
540
|
-
import {
|
|
630
|
+
```tsx
|
|
631
|
+
import {
|
|
632
|
+
defineKnownRules,
|
|
633
|
+
eslintConfigForTypeScript,
|
|
634
|
+
type FlatConfig,
|
|
635
|
+
typescriptEslintRules,
|
|
636
|
+
withDefaultOption,
|
|
637
|
+
} from 'eslint-config-typed';
|
|
541
638
|
|
|
542
|
-
|
|
543
|
-
|
|
639
|
+
const thisDir = import.meta.dirname;
|
|
640
|
+
|
|
641
|
+
export default [
|
|
642
|
+
...eslintConfigForTypeScript({
|
|
643
|
+
tsconfigRootDir: thisDir,
|
|
644
|
+
tsconfigFileName: './tsconfig.json',
|
|
645
|
+
packageDirs: [thisDir],
|
|
646
|
+
}),
|
|
544
647
|
{
|
|
545
648
|
rules: defineKnownRules({
|
|
546
649
|
// Downgrade to warning (Option settings are inherited)
|
|
547
|
-
'@typescript-eslint/no-explicit-any': 'warn',
|
|
650
|
+
'@typescript-eslint/no-explicit-any': withDefaultOption('warn'),
|
|
548
651
|
// Disable a rule
|
|
549
652
|
'@typescript-eslint/prefer-readonly-parameter-types': 'off',
|
|
550
653
|
// Configure with options
|
|
@@ -570,19 +673,18 @@ export default defineConfig([
|
|
|
570
673
|
],
|
|
571
674
|
}),
|
|
572
675
|
},
|
|
573
|
-
]
|
|
676
|
+
] satisfies FlatConfig[];
|
|
574
677
|
```
|
|
575
678
|
|
|
576
|
-
### Use
|
|
679
|
+
### Use RulesOptions Types
|
|
577
680
|
|
|
578
681
|
Leverage TypeScript for type-safe rule configuration:
|
|
579
682
|
|
|
580
|
-
```
|
|
683
|
+
```tsx
|
|
581
684
|
// configs/restricted-syntax-defs.mjs
|
|
582
685
|
|
|
583
|
-
import { eslintRules } from 'eslint-config-typed';
|
|
686
|
+
import { eslintRules, type EslintRulesOption } from 'eslint-config-typed';
|
|
584
687
|
|
|
585
|
-
/** @type {import("eslint-config-typed").EslintRulesOption["no-restricted-syntax"]} */
|
|
586
688
|
export const restrictedSyntax = [
|
|
587
689
|
...eslintRules['no-restricted-syntax'].slice(1),
|
|
588
690
|
{
|
|
@@ -592,31 +694,54 @@ export const restrictedSyntax = [
|
|
|
592
694
|
message:
|
|
593
695
|
'The variable type T should be annotated as `React.useMemo<T>` or `const v: T = React.useMemo(...)`.',
|
|
594
696
|
},
|
|
595
|
-
];
|
|
697
|
+
] satisfies EslintRulesOption['no-restricted-syntax'];
|
|
596
698
|
```
|
|
597
699
|
|
|
598
|
-
```
|
|
599
|
-
// 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';
|
|
600
709
|
|
|
601
|
-
|
|
710
|
+
const thisDir = import.meta.dirname;
|
|
602
711
|
|
|
603
|
-
export default
|
|
604
|
-
...eslintConfigForTypeScript(
|
|
712
|
+
export default [
|
|
713
|
+
...eslintConfigForTypeScript({
|
|
714
|
+
tsconfigRootDir: thisDir,
|
|
715
|
+
tsconfigFileName: './tsconfig.json',
|
|
716
|
+
packageDirs: [thisDir],
|
|
717
|
+
}),
|
|
605
718
|
{
|
|
606
719
|
rules: defineKnownRules({
|
|
607
|
-
'no-restricted-syntax': ['error', restrictedSyntax],
|
|
720
|
+
'no-restricted-syntax': ['error', ...restrictedSyntax],
|
|
608
721
|
}),
|
|
609
722
|
},
|
|
610
|
-
]
|
|
723
|
+
] satisfies readonly FlatConfig[];
|
|
611
724
|
```
|
|
612
725
|
|
|
613
726
|
### Target Specific Files
|
|
614
727
|
|
|
615
728
|
Apply different rules to different file patterns:
|
|
616
729
|
|
|
617
|
-
```
|
|
618
|
-
|
|
619
|
-
|
|
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
|
+
}),
|
|
620
745
|
{
|
|
621
746
|
files: ['**/*.test.ts', '**/*.spec.ts'],
|
|
622
747
|
rules: defineKnownRules({
|
|
@@ -631,10 +756,10 @@ export default defineConfig([
|
|
|
631
756
|
rules: defineKnownRules({
|
|
632
757
|
// Allow console in scripts
|
|
633
758
|
'no-await-in-loop': 'off',
|
|
634
|
-
'import/no-unassigned-import': 'off',
|
|
759
|
+
'import-x/no-unassigned-import': 'off',
|
|
635
760
|
}),
|
|
636
761
|
},
|
|
637
|
-
]
|
|
762
|
+
] satisfies FlatConfig[];
|
|
638
763
|
```
|
|
639
764
|
|
|
640
765
|
## Troubleshooting
|
|
@@ -645,33 +770,41 @@ export default defineConfig([
|
|
|
645
770
|
|
|
646
771
|
Ensure the paths are correct:
|
|
647
772
|
|
|
648
|
-
```
|
|
773
|
+
```tsx
|
|
774
|
+
import {
|
|
775
|
+
eslintConfigForTypeScript,
|
|
776
|
+
type FlatConfig,
|
|
777
|
+
} from 'eslint-config-typed';
|
|
778
|
+
|
|
649
779
|
const thisDir = import.meta.dirname;
|
|
650
780
|
|
|
651
|
-
export default
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
}),
|
|
657
|
-
]);
|
|
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[];
|
|
658
786
|
```
|
|
659
787
|
|
|
660
788
|
#### 2. Import resolution errors
|
|
661
789
|
|
|
662
790
|
The `packageDirs` option helps ESLint resolve imports correctly in monorepos:
|
|
663
791
|
|
|
664
|
-
```
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
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[];
|
|
675
808
|
```
|
|
676
809
|
|
|
677
810
|
#### 3. Performance issues
|
|
@@ -685,9 +818,36 @@ For large projects, consider:
|
|
|
685
818
|
- Running ESLint with `--cache` flag
|
|
686
819
|
- Limiting the scope of type-aware rules
|
|
687
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
|
+
|
|
688
849
|
### Known Limitations
|
|
689
850
|
|
|
690
|
-
- The `import/no-unused-modules` rule does not function properly with Native ESM
|
|
691
851
|
- Some type-aware rules may have performance impacts on very large codebases
|
|
692
852
|
- Flat config requires ESLint 9.0+ and may not be compatible with older tools
|
|
693
853
|
|