eslint-plugin-code-style 1.1.2 → 1.1.10
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 +853 -655
- package/index.d.ts +8 -0
- package/index.js +478 -33
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
**A powerful ESLint plugin for enforcing consistent code formatting and style rules in React/JSX projects.**
|
|
20
20
|
|
|
21
|
-
*
|
|
21
|
+
*51 auto-fixable rules to keep your codebase clean and consistent*
|
|
22
22
|
|
|
23
23
|
</div>
|
|
24
24
|
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
|
|
27
27
|
## 🎯 Why This Plugin?
|
|
28
28
|
|
|
29
|
-
This plugin provides **
|
|
29
|
+
This plugin provides **51 custom auto-fixable rules** for code formatting. Built for **ESLint v9 flat configs**.
|
|
30
30
|
|
|
31
31
|
> **Note:** ESLint [deprecated 79 formatting rules](https://eslint.org/blog/2023/10/deprecating-formatting-rules/) in v8.53.0. Our recommended configs use `@stylistic/eslint-plugin` as the replacement for these deprecated rules.
|
|
32
32
|
|
|
@@ -59,7 +59,7 @@ We provide **ready-to-use ESLint flat configuration files** that combine `eslint
|
|
|
59
59
|
|
|
60
60
|
### 💡 Why Use These Configs?
|
|
61
61
|
|
|
62
|
-
- **Complete Coverage** — Combines ESLint built-in rules, third-party plugins, and all
|
|
62
|
+
- **Complete Coverage** — Combines ESLint built-in rules, third-party plugins, and all 51 code-style rules
|
|
63
63
|
- **Ready-to-Use** — Copy the config file and start linting immediately
|
|
64
64
|
- **Battle-Tested** — These configurations have been refined through real-world usage
|
|
65
65
|
- **Fully Documented** — Each config includes detailed instructions and explanations
|
|
@@ -94,7 +94,7 @@ We provide **ready-to-use ESLint flat configuration files** that combine `eslint
|
|
|
94
94
|
<td width="50%">
|
|
95
95
|
|
|
96
96
|
### 🔧 Auto-Fixable Rules
|
|
97
|
-
All **
|
|
97
|
+
All **51 rules** support automatic fixing with `eslint --fix`. No manual code changes needed.
|
|
98
98
|
|
|
99
99
|
</td>
|
|
100
100
|
<td width="50%">
|
|
@@ -225,6 +225,10 @@ rules: {
|
|
|
225
225
|
"code-style/single-argument-on-one-line": "error",
|
|
226
226
|
"code-style/string-property-spacing": "error",
|
|
227
227
|
"code-style/variable-naming-convention": "error",
|
|
228
|
+
"code-style/enum-format": "error",
|
|
229
|
+
"code-style/interface-format": "error",
|
|
230
|
+
"code-style/type-format": "error",
|
|
231
|
+
"code-style/typescript-definition-location": "error",
|
|
228
232
|
}
|
|
229
233
|
```
|
|
230
234
|
|
|
@@ -234,34 +238,50 @@ rules: {
|
|
|
234
238
|
|
|
235
239
|
## 📖 Rules Summary
|
|
236
240
|
|
|
237
|
-
> All **
|
|
241
|
+
> All **51 rules** are auto-fixable. See detailed examples for each rule in the [Rules Reference](#-rules-reference) section below.
|
|
238
242
|
>
|
|
239
243
|
> Rules marked with ⚙️ support customization options (e.g., extending default folder lists).
|
|
240
244
|
|
|
241
245
|
| Rule | Description |
|
|
242
246
|
|------|-------------|
|
|
247
|
+
| **Array Rules** | |
|
|
243
248
|
| `array-items-per-line` | Collapse arrays ≤ threshold to one line; expand larger arrays with each item on own line (default: ≤3) ⚙️ |
|
|
244
249
|
| `array-objects-on-new-lines` | Each object in an array starts on its own line for better visual scanning |
|
|
250
|
+
| **Arrow Function Rules** | |
|
|
245
251
|
| `arrow-function-block-body` | Wrap multiline arrow function expressions in parentheses for clear boundaries |
|
|
246
252
|
| `arrow-function-simple-jsx` | Collapse arrow functions returning simple single-element JSX to one line, remove unnecessary parens |
|
|
247
253
|
| `arrow-function-simplify` | Convert block body with single return to implicit return: `() => { return x; }` → `() => x` |
|
|
248
254
|
| `curried-arrow-same-line` | Curried arrow functions start on same line as `=>`, not on new line |
|
|
249
|
-
|
|
|
250
|
-
| `
|
|
255
|
+
| **Call Expression Rules** | |
|
|
256
|
+
| `function-arguments-format` | Args ≥ threshold or multiline: first arg on new line, each on own line, closing `)` on new line (default: ≥2) ⚙️ |
|
|
257
|
+
| `nested-call-closing-brackets` | Chain closing brackets on same line: `}));` not scattered across lines |
|
|
258
|
+
| `no-empty-lines-in-function-calls` | No empty lines between arguments or after `(`/before `)` |
|
|
259
|
+
| `opening-brackets-same-line` | Opening `{`, `[`, or `(` on same line as function call, not on new line |
|
|
260
|
+
| `simple-call-single-line` | Collapse simple `fn(() => call())` patterns to single line |
|
|
261
|
+
| `single-argument-on-one-line` | Single simple argument stays on one line: `fn(x)` not expanded |
|
|
262
|
+
| **Comment Rules** | |
|
|
251
263
|
| `comment-format` | Space after `//`, space inside `/* */`, convert single-line blocks to `//`, no blank lines between file-top comments |
|
|
264
|
+
| **Control Flow Rules** | |
|
|
265
|
+
| `block-statement-newlines` | Newline after `{` and before `}` in if/for/while/function blocks |
|
|
266
|
+
| `if-statement-format` | `{` on same line as `if`/`else if`, `else` on same line as `}`, proper spacing |
|
|
267
|
+
| `multiline-if-conditions` | Conditions exceeding threshold get one operand per line with proper indentation (default: >3) ⚙️ |
|
|
268
|
+
| `no-empty-lines-in-switch-cases` | No empty line after `case X:` before code, no empty lines between cases |
|
|
269
|
+
| **Function Rules** | |
|
|
252
270
|
| `function-call-spacing` | No space between function name and `(`: `fn()` not `fn ()` |
|
|
253
271
|
| `function-naming-convention` | Functions use camelCase, start with verb (get/set/handle/is/has), handlers end with Handler |
|
|
254
272
|
| `function-params-per-line` | When multiline, each param on own line with consistent indentation |
|
|
273
|
+
| `no-empty-lines-in-function-params` | No empty lines between parameters or after `(`/before `)` |
|
|
274
|
+
| **Hook Rules** | |
|
|
255
275
|
| `hook-callback-format` | React hooks: callback on new line, deps array on separate line, proper indentation |
|
|
256
276
|
| `hook-deps-per-line` | Collapse deps ≤ threshold to one line; expand larger arrays with each dep on own line (default: >2) ⚙️ |
|
|
257
|
-
|
|
|
258
|
-
| `multiline-if-conditions` | Conditions exceeding threshold get one operand per line with proper indentation (default: >3) ⚙️ |
|
|
277
|
+
| **Import/Export Rules** | |
|
|
259
278
|
| `absolute-imports-only` | Use alias imports from index files only (not deep paths), no relative imports (default: `@/`) ⚙️ |
|
|
260
279
|
| `export-format` | `export {` on same line; collapse ≤ threshold to one line; expand larger with each specifier on own line (default: ≤3) ⚙️ |
|
|
261
280
|
| `import-format` | `import {` and `} from` on same line; collapse ≤ threshold; expand larger with each specifier on own line (default: ≤3) ⚙️ |
|
|
262
281
|
| `import-source-spacing` | No leading/trailing spaces inside import path quotes |
|
|
263
282
|
| `index-export-style` | Index files: no blank lines, enforce shorthand or import-export style; Regular files: require blank lines between exports (default: shorthand) ⚙️ |
|
|
264
283
|
| `module-index-exports` | Index files must export all folder contents (files and subfolders) ⚙️ |
|
|
284
|
+
| **JSX Rules** | |
|
|
265
285
|
| `jsx-children-on-new-line` | Multiple JSX children: each on own line with proper indentation |
|
|
266
286
|
| `jsx-closing-bracket-spacing` | No space before `>` or `/>` in JSX tags |
|
|
267
287
|
| `jsx-element-child-new-line` | Nested JSX elements on new lines; text/expression children can stay inline |
|
|
@@ -271,21 +291,22 @@ rules: {
|
|
|
271
291
|
| `jsx-simple-element-one-line` | Collapse simple JSX with single text/expression child to one line |
|
|
272
292
|
| `jsx-string-value-trim` | No leading/trailing whitespace inside JSX string attribute values |
|
|
273
293
|
| `jsx-ternary-format` | Simple ternaries on one line; complex branches get parens with proper indentation |
|
|
274
|
-
| `member-expression-bracket-spacing` | No spaces inside brackets in computed member expressions: `arr[0]` not `arr[ 0 ]` |
|
|
275
|
-
| `function-arguments-format` | Args ≥ threshold or multiline: first arg on new line, each on own line, closing `)` on new line (default: ≥2) ⚙️ |
|
|
276
|
-
| `nested-call-closing-brackets` | Chain closing brackets on same line: `}));` not scattered across lines |
|
|
277
|
-
| `no-empty-lines-in-function-calls` | No empty lines between arguments or after `(`/before `)` |
|
|
278
|
-
| `no-empty-lines-in-function-params` | No empty lines between parameters or after `(`/before `)` |
|
|
279
294
|
| `no-empty-lines-in-jsx` | No empty lines between children or after opening/before closing tags |
|
|
295
|
+
| **Object Rules** | |
|
|
280
296
|
| `no-empty-lines-in-objects` | No empty lines between properties or after `{`/before `}` |
|
|
281
|
-
| `no-empty-lines-in-switch-cases` | No empty line after `case X:` before code, no empty lines between cases |
|
|
282
297
|
| `object-property-per-line` | Collapse ≤ threshold to one line; expand larger with `{`/`}` on own lines and each property on own line (default: ≥2) ⚙️ |
|
|
283
298
|
| `object-property-value-brace` | Opening `{` of object value on same line as `:`, not on new line |
|
|
284
299
|
| `object-property-value-format` | Simple property values on same line as `:`, not on new line |
|
|
285
|
-
| `opening-brackets-same-line` | Opening `{`, `[`, or `(` on same line as function call, not on new line |
|
|
286
|
-
| `simple-call-single-line` | Collapse simple `fn(() => call())` patterns to single line |
|
|
287
|
-
| `single-argument-on-one-line` | Single simple argument stays on one line: `fn(x)` not expanded |
|
|
288
300
|
| `string-property-spacing` | No leading/trailing spaces inside string property keys |
|
|
301
|
+
| **Spacing Rules** | |
|
|
302
|
+
| `assignment-value-same-line` | Assignment values start on same line as `=`, not on new line |
|
|
303
|
+
| `member-expression-bracket-spacing` | No spaces inside brackets in computed member expressions: `arr[0]` not `arr[ 0 ]` |
|
|
304
|
+
| **TypeScript Rules** | |
|
|
305
|
+
| `enum-format` | Enforce enum naming (PascalCase + Enum suffix), UPPER_CASE members, no empty lines, and trailing commas |
|
|
306
|
+
| `interface-format` | Enforce interface naming (PascalCase + Interface suffix), camelCase properties, no empty lines, and trailing commas |
|
|
307
|
+
| `type-format` | Enforce type naming (PascalCase + Type suffix), camelCase properties, no empty lines, and trailing commas |
|
|
308
|
+
| `typescript-definition-location` | Enforce TypeScript definitions (interfaces, types, enums) to be in designated folders ⚙️ |
|
|
309
|
+
| **Variable Rules** | |
|
|
289
310
|
| `variable-naming-convention` | camelCase for variables, UPPER_CASE for constants, PascalCase for components, `use` prefix for hooks |
|
|
290
311
|
|
|
291
312
|
<br />
|
|
@@ -484,196 +505,528 @@ const mapDispatch = () =>
|
|
|
484
505
|
|
|
485
506
|
<br />
|
|
486
507
|
|
|
487
|
-
##
|
|
508
|
+
## 📞 Call Expression Rules
|
|
488
509
|
|
|
489
|
-
### `
|
|
510
|
+
### `function-arguments-format`
|
|
490
511
|
|
|
491
|
-
**What it does:**
|
|
512
|
+
**What it does:** Enforces consistent formatting for function call arguments:
|
|
513
|
+
- Single simple argument stays on one line
|
|
514
|
+
- 2+ arguments get one per line
|
|
515
|
+
- Multiline arguments trigger full expansion
|
|
516
|
+
- React hooks are skipped by default (they have their own rule)
|
|
492
517
|
|
|
493
|
-
**Why use it:**
|
|
518
|
+
**Why use it:** Consistent argument formatting makes function calls scannable and diffs clean when adding/removing arguments.
|
|
494
519
|
|
|
495
520
|
```javascript
|
|
496
|
-
// ✅ Good —
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
port: 3000,
|
|
501
|
-
};
|
|
502
|
-
const items = [
|
|
503
|
-
"first",
|
|
504
|
-
"second",
|
|
505
|
-
];
|
|
506
|
-
|
|
507
|
-
// ❌ Bad — value on new line after =
|
|
508
|
-
const name =
|
|
509
|
-
"John";
|
|
510
|
-
const config =
|
|
511
|
-
{
|
|
512
|
-
host: "localhost",
|
|
513
|
-
port: 3000,
|
|
514
|
-
};
|
|
515
|
-
const items =
|
|
516
|
-
[
|
|
517
|
-
"first",
|
|
518
|
-
"second",
|
|
519
|
-
];
|
|
520
|
-
```
|
|
521
|
-
|
|
522
|
-
---
|
|
523
|
-
|
|
524
|
-
### `block-statement-newlines`
|
|
525
|
-
|
|
526
|
-
**What it does:** Enforces newlines after the opening brace `{` and before the closing brace `}` in block statements (if, for, while, etc.).
|
|
527
|
-
|
|
528
|
-
**Why use it:** Consistent block formatting improves readability. Single-line blocks are harder to scan and edit.
|
|
521
|
+
// ✅ Good — single argument stays compact
|
|
522
|
+
fetchUser(userId);
|
|
523
|
+
console.log(message);
|
|
524
|
+
dispatch(action);
|
|
529
525
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
526
|
+
// ✅ Good — 2+ arguments get one per line
|
|
527
|
+
setValue(
|
|
528
|
+
"email",
|
|
529
|
+
"user@example.com",
|
|
530
|
+
);
|
|
535
531
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
532
|
+
createUser(
|
|
533
|
+
name,
|
|
534
|
+
email,
|
|
535
|
+
password,
|
|
536
|
+
);
|
|
539
537
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
538
|
+
// ✅ Good — multiline argument triggers expansion
|
|
539
|
+
processData(
|
|
540
|
+
{
|
|
541
|
+
id: 1,
|
|
542
|
+
name: "test",
|
|
543
|
+
},
|
|
544
|
+
);
|
|
543
545
|
|
|
544
|
-
//
|
|
545
|
-
|
|
546
|
+
// ✅ Good — callback with body triggers expansion
|
|
547
|
+
items.forEach(
|
|
548
|
+
(item) => {
|
|
549
|
+
process(item);
|
|
550
|
+
save(item);
|
|
551
|
+
},
|
|
552
|
+
);
|
|
546
553
|
|
|
547
|
-
// ❌ Bad —
|
|
548
|
-
|
|
554
|
+
// ❌ Bad — multiple arguments on same line
|
|
555
|
+
setValue("email", "user@example.com");
|
|
556
|
+
createUser(name, email, password);
|
|
549
557
|
|
|
550
558
|
// ❌ Bad — inconsistent formatting
|
|
551
|
-
|
|
552
|
-
|
|
559
|
+
fn(arg1,
|
|
560
|
+
arg2, arg3);
|
|
553
561
|
```
|
|
554
562
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
### `comment-format`
|
|
558
|
-
|
|
559
|
-
**What it does:** Enforces proper comment formatting:
|
|
560
|
-
- Space after `//` in line comments
|
|
561
|
-
- Space after `/*` and before `*/` in block comments
|
|
562
|
-
- Single-line block comments converted to line comments
|
|
563
|
-
- No blank lines between consecutive comments at file top
|
|
563
|
+
**Options:**
|
|
564
564
|
|
|
565
|
-
|
|
565
|
+
| Option | Type | Default | Description |
|
|
566
|
+
|--------|------|---------|-------------|
|
|
567
|
+
| `minArgs` | `integer` | `2` | Minimum arguments to enforce multiline |
|
|
568
|
+
| `skipHooks` | `boolean` | `true` | Skip React hooks (useEffect, etc.) |
|
|
569
|
+
| `skipSingleArg` | `boolean` | `true` | Skip calls with single complex argument |
|
|
566
570
|
|
|
567
571
|
```javascript
|
|
568
|
-
//
|
|
569
|
-
|
|
570
|
-
/* This is a block comment */
|
|
571
|
-
|
|
572
|
-
/*
|
|
573
|
-
* This is a multi-line
|
|
574
|
-
* block comment
|
|
575
|
-
*/
|
|
576
|
-
|
|
577
|
-
// ✅ Good — file-top comments without gaps
|
|
578
|
-
// File: utils.js
|
|
579
|
-
// Author: John Doe
|
|
580
|
-
// License: MIT
|
|
581
|
-
|
|
582
|
-
// ❌ Bad — missing space after //
|
|
583
|
-
//This is a comment
|
|
584
|
-
|
|
585
|
-
// ❌ Bad — no space in block comment
|
|
586
|
-
/*No space*/
|
|
572
|
+
// Example: Require multiline for 3+ arguments
|
|
573
|
+
"code-style/function-arguments-format": ["error", { minArgs: 3 }]
|
|
587
574
|
|
|
588
|
-
//
|
|
589
|
-
|
|
575
|
+
// Example: Don't skip React hooks
|
|
576
|
+
"code-style/function-arguments-format": ["error", { skipHooks: false }]
|
|
590
577
|
```
|
|
591
578
|
|
|
592
579
|
---
|
|
593
580
|
|
|
594
|
-
### `
|
|
581
|
+
### `nested-call-closing-brackets`
|
|
595
582
|
|
|
596
|
-
**What it does:**
|
|
583
|
+
**What it does:** Ensures nested function calls (common in styled-components, HOCs) have closing brackets on the same line: `}));`
|
|
597
584
|
|
|
598
|
-
**Why use it:**
|
|
585
|
+
**Why use it:** Scattered closing brackets (`}\n);\n` ) waste vertical space and make it harder to see where expressions end.
|
|
599
586
|
|
|
600
587
|
```javascript
|
|
601
|
-
// ✅ Good —
|
|
602
|
-
const
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
588
|
+
// ✅ Good — closing brackets together
|
|
589
|
+
const StyledCard = styled(Card)(({ theme }) => ({
|
|
590
|
+
color: theme.palette.text.primary,
|
|
591
|
+
padding: theme.spacing(2),
|
|
592
|
+
}));
|
|
606
593
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
594
|
+
const StyledButton = styled("button")(({ theme }) => ({
|
|
595
|
+
backgroundColor: theme.colors.primary,
|
|
596
|
+
}));
|
|
597
|
+
|
|
598
|
+
// ✅ Good — multiple levels
|
|
599
|
+
const Component = connect(
|
|
600
|
+
mapStateToProps,
|
|
601
|
+
mapDispatchToProps,
|
|
602
|
+
)(withRouter(MyComponent));
|
|
603
|
+
|
|
604
|
+
// ❌ Bad — closing brackets scattered
|
|
605
|
+
const StyledCard = styled(Card)(({ theme }) => ({
|
|
606
|
+
color: theme.palette.text.primary,
|
|
607
|
+
})
|
|
608
|
+
);
|
|
609
|
+
|
|
610
|
+
// ❌ Bad — each bracket on its own line
|
|
611
|
+
const StyledCard = styled(Card)(({ theme }) => ({
|
|
612
|
+
color: theme.colors.primary,
|
|
613
|
+
})
|
|
614
|
+
)
|
|
615
|
+
;
|
|
611
616
|
```
|
|
612
617
|
|
|
613
618
|
---
|
|
614
619
|
|
|
615
|
-
### `no-empty-lines-in-function-
|
|
620
|
+
### `no-empty-lines-in-function-calls`
|
|
616
621
|
|
|
617
|
-
**What it does:** Removes empty lines within function
|
|
622
|
+
**What it does:** Removes empty lines within function call argument lists — between arguments and after opening/before closing parentheses.
|
|
618
623
|
|
|
619
|
-
**Why use it:** Empty lines
|
|
624
|
+
**Why use it:** Empty lines between arguments break visual grouping. Arguments should flow as a cohesive list.
|
|
620
625
|
|
|
621
626
|
```javascript
|
|
622
627
|
// ✅ Good — no empty lines
|
|
623
|
-
|
|
628
|
+
createUser(
|
|
624
629
|
name,
|
|
625
630
|
email,
|
|
631
|
+
password,
|
|
626
632
|
role,
|
|
627
|
-
)
|
|
633
|
+
);
|
|
628
634
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
635
|
+
fetchData(
|
|
636
|
+
url,
|
|
637
|
+
{
|
|
638
|
+
method: "POST",
|
|
639
|
+
body: data,
|
|
640
|
+
},
|
|
641
|
+
);
|
|
633
642
|
|
|
634
|
-
// ❌ Bad — empty line between
|
|
635
|
-
|
|
643
|
+
// ❌ Bad — empty line between arguments
|
|
644
|
+
createUser(
|
|
636
645
|
name,
|
|
637
646
|
|
|
638
647
|
email,
|
|
639
648
|
|
|
640
|
-
|
|
641
|
-
)
|
|
649
|
+
password,
|
|
650
|
+
);
|
|
642
651
|
|
|
643
652
|
// ❌ Bad — empty line after opening paren
|
|
644
|
-
|
|
653
|
+
fetchData(
|
|
645
654
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
)
|
|
655
|
+
url,
|
|
656
|
+
options,
|
|
657
|
+
);
|
|
658
|
+
|
|
659
|
+
// ❌ Bad — empty line before closing paren
|
|
660
|
+
fetchData(
|
|
661
|
+
url,
|
|
662
|
+
options,
|
|
663
|
+
|
|
664
|
+
);
|
|
649
665
|
```
|
|
650
666
|
|
|
651
667
|
---
|
|
652
668
|
|
|
653
|
-
### `
|
|
669
|
+
### `opening-brackets-same-line`
|
|
654
670
|
|
|
655
|
-
**What it does:**
|
|
656
|
-
- **camelCase** for regular variables and functions
|
|
657
|
-
- **UPPER_CASE** for constants (primitive values)
|
|
658
|
-
- **PascalCase** for React components and classes
|
|
659
|
-
- **camelCase with `use` prefix** for hooks
|
|
671
|
+
**What it does:** Ensures opening brackets (`{`, `[`, `(`) in function arguments stay on the same line as the function call.
|
|
660
672
|
|
|
661
|
-
**Why use it:**
|
|
673
|
+
**Why use it:** Opening brackets on new lines create unnecessary indentation and vertical space.
|
|
674
|
+
|
|
675
|
+
```javascript
|
|
676
|
+
// ✅ Good — brackets on same line as call
|
|
677
|
+
fn({ key: value });
|
|
678
|
+
process([1, 2, 3]);
|
|
679
|
+
items.map(({ id }) => id);
|
|
680
|
+
configure({ debug: true });
|
|
681
|
+
|
|
682
|
+
// ✅ Good — multiline content is fine
|
|
683
|
+
fn({
|
|
684
|
+
key: value,
|
|
685
|
+
other: data,
|
|
686
|
+
});
|
|
687
|
+
|
|
688
|
+
items.map(({ id, name }) => (
|
|
689
|
+
<Item key={id} name={name} />
|
|
690
|
+
));
|
|
691
|
+
|
|
692
|
+
// ❌ Bad — opening bracket on new line
|
|
693
|
+
fn(
|
|
694
|
+
{ key: value }
|
|
695
|
+
);
|
|
696
|
+
|
|
697
|
+
process(
|
|
698
|
+
[1, 2, 3]
|
|
699
|
+
);
|
|
700
|
+
|
|
701
|
+
items.map(
|
|
702
|
+
({ id }) => id
|
|
703
|
+
);
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
---
|
|
707
|
+
|
|
708
|
+
### `simple-call-single-line`
|
|
709
|
+
|
|
710
|
+
**What it does:** Collapses simple function calls with an arrow function containing a single call expression onto one line.
|
|
711
|
+
|
|
712
|
+
**Why use it:** Common patterns like `lazy(() => import(...))` don't need multiline formatting. Single line is cleaner.
|
|
713
|
+
|
|
714
|
+
```javascript
|
|
715
|
+
// ✅ Good — simple patterns on one line
|
|
716
|
+
const Page = lazy(() => import("./Page"));
|
|
717
|
+
const Modal = lazy(() => import("./Modal"));
|
|
718
|
+
setTimeout(() => callback(), 100);
|
|
719
|
+
requestAnimationFrame(() => render());
|
|
720
|
+
items.filter(() => isValid(item));
|
|
721
|
+
|
|
722
|
+
// ✅ Good — complex callbacks stay multiline
|
|
723
|
+
const Page = lazy(() => {
|
|
724
|
+
console.log("Loading page");
|
|
725
|
+
return import("./Page");
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
// ❌ Bad — unnecessary multiline for simple pattern
|
|
729
|
+
const Page = lazy(
|
|
730
|
+
() => import("./Page"),
|
|
731
|
+
);
|
|
732
|
+
|
|
733
|
+
setTimeout(
|
|
734
|
+
() => callback(),
|
|
735
|
+
100,
|
|
736
|
+
);
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
---
|
|
740
|
+
|
|
741
|
+
### `single-argument-on-one-line`
|
|
742
|
+
|
|
743
|
+
**What it does:** Ensures function calls with a single simple argument (literal, identifier, member expression) stay on one line.
|
|
744
|
+
|
|
745
|
+
**Why use it:** Single-argument calls don't need multiline formatting. Expanding them wastes vertical space.
|
|
746
|
+
|
|
747
|
+
```javascript
|
|
748
|
+
// ✅ Good — single argument on one line
|
|
749
|
+
fetchUser(userId);
|
|
750
|
+
console.log(message);
|
|
751
|
+
process(data.items);
|
|
752
|
+
dispatch(action);
|
|
753
|
+
setValue("key");
|
|
754
|
+
getElement(document.body);
|
|
755
|
+
|
|
756
|
+
// ✅ Good — complex single argument can be multiline
|
|
757
|
+
processConfig({
|
|
758
|
+
key: value,
|
|
759
|
+
other: data,
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
// ❌ Bad — simple argument expanded unnecessarily
|
|
763
|
+
fetchUser(
|
|
764
|
+
userId,
|
|
765
|
+
);
|
|
766
|
+
|
|
767
|
+
console.log(
|
|
768
|
+
message,
|
|
769
|
+
);
|
|
770
|
+
|
|
771
|
+
dispatch(
|
|
772
|
+
action,
|
|
773
|
+
);
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
<br />
|
|
777
|
+
|
|
778
|
+
## 💬 Comment Rules
|
|
779
|
+
|
|
780
|
+
### `comment-format`
|
|
781
|
+
|
|
782
|
+
**What it does:** Enforces proper comment formatting:
|
|
783
|
+
- Space after `//` in line comments
|
|
784
|
+
- Space after `/*` and before `*/` in block comments
|
|
785
|
+
- Single-line block comments converted to line comments
|
|
786
|
+
- No blank lines between consecutive comments at file top
|
|
787
|
+
|
|
788
|
+
**Why use it:** Consistent comment formatting improves readability and maintains a clean, professional codebase.
|
|
789
|
+
|
|
790
|
+
```javascript
|
|
791
|
+
// ✅ Good — proper spacing
|
|
792
|
+
// This is a comment
|
|
793
|
+
/* This is a block comment */
|
|
794
|
+
|
|
795
|
+
/*
|
|
796
|
+
* This is a multi-line
|
|
797
|
+
* block comment
|
|
798
|
+
*/
|
|
799
|
+
|
|
800
|
+
// ✅ Good — file-top comments without gaps
|
|
801
|
+
// File: utils.js
|
|
802
|
+
// Author: John Doe
|
|
803
|
+
// License: MIT
|
|
804
|
+
|
|
805
|
+
// ❌ Bad — missing space after //
|
|
806
|
+
//This is a comment
|
|
807
|
+
|
|
808
|
+
// ❌ Bad — no space in block comment
|
|
809
|
+
/*No space*/
|
|
810
|
+
|
|
811
|
+
// ❌ Bad — single-line block should be line comment
|
|
812
|
+
/* This should use // syntax */
|
|
813
|
+
```
|
|
814
|
+
|
|
815
|
+
<br />
|
|
816
|
+
|
|
817
|
+
## 🔀 Control Flow Rules
|
|
818
|
+
|
|
819
|
+
### `block-statement-newlines`
|
|
820
|
+
|
|
821
|
+
**What it does:** Enforces newlines after the opening brace `{` and before the closing brace `}` in block statements (if, for, while, etc.).
|
|
822
|
+
|
|
823
|
+
**Why use it:** Consistent block formatting improves readability. Single-line blocks are harder to scan and edit.
|
|
824
|
+
|
|
825
|
+
```javascript
|
|
826
|
+
// ✅ Good — proper block formatting
|
|
827
|
+
if (condition) {
|
|
828
|
+
doSomething();
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
for (const item of items) {
|
|
832
|
+
process(item);
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
while (running) {
|
|
836
|
+
tick();
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
// ❌ Bad — everything on one line
|
|
840
|
+
if (condition) { doSomething(); }
|
|
841
|
+
|
|
842
|
+
// ❌ Bad — no space after brace
|
|
843
|
+
if (condition) {doSomething();}
|
|
844
|
+
|
|
845
|
+
// ❌ Bad — inconsistent formatting
|
|
846
|
+
for (const item of items) { process(item);
|
|
847
|
+
}
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
---
|
|
851
|
+
|
|
852
|
+
### `if-statement-format`
|
|
853
|
+
|
|
854
|
+
**What it does:** Enforces consistent if/else formatting:
|
|
855
|
+
- Opening `{` on the same line as `if`/`else if`/`else`
|
|
856
|
+
- `else` on the same line as the closing `}`
|
|
857
|
+
- Proper spacing around keywords
|
|
858
|
+
|
|
859
|
+
**Why use it:** Consistent brace placement reduces visual noise and follows the most common JavaScript style (K&R / "one true brace style").
|
|
860
|
+
|
|
861
|
+
```javascript
|
|
862
|
+
// ✅ Good — consistent formatting
|
|
863
|
+
if (condition) {
|
|
864
|
+
doSomething();
|
|
865
|
+
|
|
866
|
+
doMore();
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
if (condition) {
|
|
870
|
+
doSomething();
|
|
871
|
+
|
|
872
|
+
doMore();
|
|
873
|
+
} else {
|
|
874
|
+
doOther();
|
|
875
|
+
|
|
876
|
+
doAnother();
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
if (conditionA) {
|
|
880
|
+
handleA();
|
|
881
|
+
|
|
882
|
+
processA();
|
|
883
|
+
} else if (conditionB) {
|
|
884
|
+
handleB();
|
|
885
|
+
|
|
886
|
+
processB();
|
|
887
|
+
} else {
|
|
888
|
+
handleDefault();
|
|
889
|
+
|
|
890
|
+
processDefault();
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
// ❌ Bad — brace on new line
|
|
894
|
+
if (condition)
|
|
895
|
+
{
|
|
896
|
+
doSomething();
|
|
897
|
+
|
|
898
|
+
doMore();
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
// ❌ Bad — else on new line
|
|
902
|
+
if (condition) {
|
|
903
|
+
doSomething();
|
|
904
|
+
|
|
905
|
+
doMore();
|
|
906
|
+
}
|
|
907
|
+
else {
|
|
908
|
+
doOther();
|
|
909
|
+
|
|
910
|
+
doAnother();
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
// ❌ Bad — inconsistent formatting
|
|
914
|
+
if (condition)
|
|
915
|
+
{
|
|
916
|
+
doSomething();
|
|
917
|
+
|
|
918
|
+
doMore();
|
|
919
|
+
}
|
|
920
|
+
else
|
|
921
|
+
{
|
|
922
|
+
doOther();
|
|
923
|
+
|
|
924
|
+
doAnother();
|
|
925
|
+
}
|
|
926
|
+
```
|
|
927
|
+
|
|
928
|
+
---
|
|
929
|
+
|
|
930
|
+
### `multiline-if-conditions`
|
|
931
|
+
|
|
932
|
+
**What it does:** When an if statement has more conditions than the threshold (default: 3), each condition goes on its own line with proper indentation.
|
|
933
|
+
|
|
934
|
+
**Why use it:** Long conditions are hard to read on one line. One per line makes each condition clear and easy to modify.
|
|
935
|
+
|
|
936
|
+
```javascript
|
|
937
|
+
// ✅ Good — 3 or fewer conditions stay inline
|
|
938
|
+
if (isValid && isActive) {}
|
|
939
|
+
if (a && b && c) {}
|
|
940
|
+
|
|
941
|
+
// ✅ Good — 4+ conditions get one per line
|
|
942
|
+
if (
|
|
943
|
+
isAuthenticated &&
|
|
944
|
+
hasPermission &&
|
|
945
|
+
!isExpired &&
|
|
946
|
+
isEnabled
|
|
947
|
+
) {
|
|
948
|
+
allowAccess();
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
if (
|
|
952
|
+
user.isAdmin ||
|
|
953
|
+
user.isModerator ||
|
|
954
|
+
user.hasSpecialAccess ||
|
|
955
|
+
isPublicResource
|
|
956
|
+
) {
|
|
957
|
+
showContent();
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
// ❌ Bad — too many conditions on one line
|
|
961
|
+
if (isAuthenticated && hasPermission && !isExpired && isEnabled) {}
|
|
962
|
+
|
|
963
|
+
// ❌ Bad — inconsistent formatting
|
|
964
|
+
if (isAuthenticated &&
|
|
965
|
+
hasPermission && !isExpired &&
|
|
966
|
+
isEnabled) {}
|
|
967
|
+
```
|
|
968
|
+
|
|
969
|
+
**Options:**
|
|
970
|
+
|
|
971
|
+
| Option | Type | Default | Description |
|
|
972
|
+
|--------|------|---------|-------------|
|
|
973
|
+
| `maxOperands` | `integer` | `3` | Maximum operands to keep on single line |
|
|
974
|
+
|
|
975
|
+
```javascript
|
|
976
|
+
// Example: Allow up to 4 operands on single line
|
|
977
|
+
"code-style/multiline-if-conditions": ["error", { maxOperands: 4 }]
|
|
978
|
+
```
|
|
979
|
+
|
|
980
|
+
---
|
|
981
|
+
|
|
982
|
+
### `no-empty-lines-in-switch-cases`
|
|
983
|
+
|
|
984
|
+
**What it does:** Removes empty lines at the start of case blocks and between consecutive case statements.
|
|
985
|
+
|
|
986
|
+
**Why use it:** Empty lines inside switch cases create unnecessary gaps. Cases should flow together as a cohesive block.
|
|
987
|
+
|
|
988
|
+
```javascript
|
|
989
|
+
// ✅ Good — no empty lines
|
|
990
|
+
switch (status) {
|
|
991
|
+
case "pending":
|
|
992
|
+
return "Waiting...";
|
|
993
|
+
case "success":
|
|
994
|
+
return "Done!";
|
|
995
|
+
case "error":
|
|
996
|
+
return "Failed";
|
|
997
|
+
default:
|
|
998
|
+
return "Unknown";
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
// ✅ Good — fall-through cases grouped
|
|
1002
|
+
switch (day) {
|
|
1003
|
+
case "Saturday":
|
|
1004
|
+
case "Sunday":
|
|
1005
|
+
return "Weekend";
|
|
1006
|
+
default:
|
|
1007
|
+
return "Weekday";
|
|
1008
|
+
}
|
|
662
1009
|
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
const itemCount = 42; // camelCase for variables
|
|
667
|
-
const MAX_RETRIES = 3; // UPPER_CASE for constants
|
|
668
|
-
const API_BASE_URL = "/api"; // UPPER_CASE for constants
|
|
669
|
-
const UserProfile = () => <div />; // PascalCase for components
|
|
670
|
-
const useAuth = () => {}; // camelCase with use prefix for hooks
|
|
1010
|
+
// ❌ Bad — empty line after case label
|
|
1011
|
+
switch (status) {
|
|
1012
|
+
case "pending":
|
|
671
1013
|
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
1014
|
+
return "Waiting...";
|
|
1015
|
+
case "success":
|
|
1016
|
+
return "Done!";
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
// ❌ Bad — empty lines between cases
|
|
1020
|
+
switch (status) {
|
|
1021
|
+
case "pending":
|
|
1022
|
+
return "Waiting...";
|
|
1023
|
+
|
|
1024
|
+
case "success":
|
|
1025
|
+
return "Done!";
|
|
1026
|
+
|
|
1027
|
+
default:
|
|
1028
|
+
return "Unknown";
|
|
1029
|
+
}
|
|
677
1030
|
```
|
|
678
1031
|
|
|
679
1032
|
<br />
|
|
@@ -772,9 +1125,47 @@ const handler = (event, context,
|
|
|
772
1125
|
callback) => {};
|
|
773
1126
|
```
|
|
774
1127
|
|
|
1128
|
+
---
|
|
1129
|
+
|
|
1130
|
+
### `no-empty-lines-in-function-params`
|
|
1131
|
+
|
|
1132
|
+
**What it does:** Removes empty lines within function parameter lists — between parameters and after opening/before closing parentheses.
|
|
1133
|
+
|
|
1134
|
+
**Why use it:** Empty lines in parameter lists waste space and make parameters harder to scan as a group.
|
|
1135
|
+
|
|
1136
|
+
```javascript
|
|
1137
|
+
// ✅ Good — no empty lines
|
|
1138
|
+
function createUser(
|
|
1139
|
+
name,
|
|
1140
|
+
email,
|
|
1141
|
+
role,
|
|
1142
|
+
) {}
|
|
1143
|
+
|
|
1144
|
+
const handler = (
|
|
1145
|
+
event,
|
|
1146
|
+
context,
|
|
1147
|
+
) => {};
|
|
1148
|
+
|
|
1149
|
+
// ❌ Bad — empty line between params
|
|
1150
|
+
function createUser(
|
|
1151
|
+
name,
|
|
1152
|
+
|
|
1153
|
+
email,
|
|
1154
|
+
|
|
1155
|
+
role,
|
|
1156
|
+
) {}
|
|
1157
|
+
|
|
1158
|
+
// ❌ Bad — empty line after opening paren
|
|
1159
|
+
const handler = (
|
|
1160
|
+
|
|
1161
|
+
event,
|
|
1162
|
+
context,
|
|
1163
|
+
) => {};
|
|
1164
|
+
```
|
|
1165
|
+
|
|
775
1166
|
<br />
|
|
776
1167
|
|
|
777
|
-
## 🪝
|
|
1168
|
+
## 🪝 Hook Rules
|
|
778
1169
|
|
|
779
1170
|
### `hook-callback-format`
|
|
780
1171
|
|
|
@@ -875,190 +1266,6 @@ useEffect(() => {}, [
|
|
|
875
1266
|
|
|
876
1267
|
<br />
|
|
877
1268
|
|
|
878
|
-
## 🔀 Control Flow Rules
|
|
879
|
-
|
|
880
|
-
### `if-statement-format`
|
|
881
|
-
|
|
882
|
-
**What it does:** Enforces consistent if/else formatting:
|
|
883
|
-
- Opening `{` on the same line as `if`/`else if`/`else`
|
|
884
|
-
- `else` on the same line as the closing `}`
|
|
885
|
-
- Proper spacing around keywords
|
|
886
|
-
|
|
887
|
-
**Why use it:** Consistent brace placement reduces visual noise and follows the most common JavaScript style (K&R / "one true brace style").
|
|
888
|
-
|
|
889
|
-
```javascript
|
|
890
|
-
// ✅ Good — consistent formatting
|
|
891
|
-
if (condition) {
|
|
892
|
-
doSomething();
|
|
893
|
-
|
|
894
|
-
doMore();
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
if (condition) {
|
|
898
|
-
doSomething();
|
|
899
|
-
|
|
900
|
-
doMore();
|
|
901
|
-
} else {
|
|
902
|
-
doOther();
|
|
903
|
-
|
|
904
|
-
doAnother();
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
if (conditionA) {
|
|
908
|
-
handleA();
|
|
909
|
-
|
|
910
|
-
processA();
|
|
911
|
-
} else if (conditionB) {
|
|
912
|
-
handleB();
|
|
913
|
-
|
|
914
|
-
processB();
|
|
915
|
-
} else {
|
|
916
|
-
handleDefault();
|
|
917
|
-
|
|
918
|
-
processDefault();
|
|
919
|
-
}
|
|
920
|
-
|
|
921
|
-
// ❌ Bad — brace on new line
|
|
922
|
-
if (condition)
|
|
923
|
-
{
|
|
924
|
-
doSomething();
|
|
925
|
-
|
|
926
|
-
doMore();
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
// ❌ Bad — else on new line
|
|
930
|
-
if (condition) {
|
|
931
|
-
doSomething();
|
|
932
|
-
|
|
933
|
-
doMore();
|
|
934
|
-
}
|
|
935
|
-
else {
|
|
936
|
-
doOther();
|
|
937
|
-
|
|
938
|
-
doAnother();
|
|
939
|
-
}
|
|
940
|
-
|
|
941
|
-
// ❌ Bad — inconsistent formatting
|
|
942
|
-
if (condition)
|
|
943
|
-
{
|
|
944
|
-
doSomething();
|
|
945
|
-
|
|
946
|
-
doMore();
|
|
947
|
-
}
|
|
948
|
-
else
|
|
949
|
-
{
|
|
950
|
-
doOther();
|
|
951
|
-
|
|
952
|
-
doAnother();
|
|
953
|
-
}
|
|
954
|
-
```
|
|
955
|
-
|
|
956
|
-
---
|
|
957
|
-
|
|
958
|
-
### `multiline-if-conditions`
|
|
959
|
-
|
|
960
|
-
**What it does:** When an if statement has more conditions than the threshold (default: 3), each condition goes on its own line with proper indentation.
|
|
961
|
-
|
|
962
|
-
**Why use it:** Long conditions are hard to read on one line. One per line makes each condition clear and easy to modify.
|
|
963
|
-
|
|
964
|
-
```javascript
|
|
965
|
-
// ✅ Good — 3 or fewer conditions stay inline
|
|
966
|
-
if (isValid && isActive) {}
|
|
967
|
-
if (a && b && c) {}
|
|
968
|
-
|
|
969
|
-
// ✅ Good — 4+ conditions get one per line
|
|
970
|
-
if (
|
|
971
|
-
isAuthenticated &&
|
|
972
|
-
hasPermission &&
|
|
973
|
-
!isExpired &&
|
|
974
|
-
isEnabled
|
|
975
|
-
) {
|
|
976
|
-
allowAccess();
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
if (
|
|
980
|
-
user.isAdmin ||
|
|
981
|
-
user.isModerator ||
|
|
982
|
-
user.hasSpecialAccess ||
|
|
983
|
-
isPublicResource
|
|
984
|
-
) {
|
|
985
|
-
showContent();
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
// ❌ Bad — too many conditions on one line
|
|
989
|
-
if (isAuthenticated && hasPermission && !isExpired && isEnabled) {}
|
|
990
|
-
|
|
991
|
-
// ❌ Bad — inconsistent formatting
|
|
992
|
-
if (isAuthenticated &&
|
|
993
|
-
hasPermission && !isExpired &&
|
|
994
|
-
isEnabled) {}
|
|
995
|
-
```
|
|
996
|
-
|
|
997
|
-
**Options:**
|
|
998
|
-
|
|
999
|
-
| Option | Type | Default | Description |
|
|
1000
|
-
|--------|------|---------|-------------|
|
|
1001
|
-
| `maxOperands` | `integer` | `3` | Maximum operands to keep on single line |
|
|
1002
|
-
|
|
1003
|
-
```javascript
|
|
1004
|
-
// Example: Allow up to 4 operands on single line
|
|
1005
|
-
"code-style/multiline-if-conditions": ["error", { maxOperands: 4 }]
|
|
1006
|
-
```
|
|
1007
|
-
|
|
1008
|
-
---
|
|
1009
|
-
|
|
1010
|
-
### `no-empty-lines-in-switch-cases`
|
|
1011
|
-
|
|
1012
|
-
**What it does:** Removes empty lines at the start of case blocks and between consecutive case statements.
|
|
1013
|
-
|
|
1014
|
-
**Why use it:** Empty lines inside switch cases create unnecessary gaps. Cases should flow together as a cohesive block.
|
|
1015
|
-
|
|
1016
|
-
```javascript
|
|
1017
|
-
// ✅ Good — no empty lines
|
|
1018
|
-
switch (status) {
|
|
1019
|
-
case "pending":
|
|
1020
|
-
return "Waiting...";
|
|
1021
|
-
case "success":
|
|
1022
|
-
return "Done!";
|
|
1023
|
-
case "error":
|
|
1024
|
-
return "Failed";
|
|
1025
|
-
default:
|
|
1026
|
-
return "Unknown";
|
|
1027
|
-
}
|
|
1028
|
-
|
|
1029
|
-
// ✅ Good — fall-through cases grouped
|
|
1030
|
-
switch (day) {
|
|
1031
|
-
case "Saturday":
|
|
1032
|
-
case "Sunday":
|
|
1033
|
-
return "Weekend";
|
|
1034
|
-
default:
|
|
1035
|
-
return "Weekday";
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
// ❌ Bad — empty line after case label
|
|
1039
|
-
switch (status) {
|
|
1040
|
-
case "pending":
|
|
1041
|
-
|
|
1042
|
-
return "Waiting...";
|
|
1043
|
-
case "success":
|
|
1044
|
-
return "Done!";
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
// ❌ Bad — empty lines between cases
|
|
1048
|
-
switch (status) {
|
|
1049
|
-
case "pending":
|
|
1050
|
-
return "Waiting...";
|
|
1051
|
-
|
|
1052
|
-
case "success":
|
|
1053
|
-
return "Done!";
|
|
1054
|
-
|
|
1055
|
-
default:
|
|
1056
|
-
return "Unknown";
|
|
1057
|
-
}
|
|
1058
|
-
```
|
|
1059
|
-
|
|
1060
|
-
<br />
|
|
1061
|
-
|
|
1062
1269
|
## 📥 Import/Export Rules
|
|
1063
1270
|
|
|
1064
1271
|
### `absolute-imports-only`
|
|
@@ -1092,7 +1299,7 @@ import { fetchUsers } from "@/apis/users/fetchUsers";
|
|
|
1092
1299
|
```
|
|
1093
1300
|
|
|
1094
1301
|
**Default Allowed Folders:**
|
|
1095
|
-
`actions`, `apis`, `assets`, `atoms`, `components`, `constants`, `contexts`, `data`, `hooks`, `layouts`, `middlewares`, `providers`, `reducers`, `redux`, `requests`, `routes`, `schemas`, `services`, `store`, `styles`, `theme`, `thunks`, `types`, `utils`, `views`
|
|
1302
|
+
`actions`, `apis`, `assets`, `atoms`, `components`, `constants`, `contexts`, `data`, `enums`, `hooks`, `interfaces`, `layouts`, `middlewares`, `providers`, `reducers`, `redux`, `requests`, `routes`, `schemas`, `services`, `store`, `styles`, `theme`, `thunks`, `types`, `utils`, `views`
|
|
1096
1303
|
|
|
1097
1304
|
**Customization Options:**
|
|
1098
1305
|
|
|
@@ -1336,7 +1543,7 @@ import { Button } from "@/components/Button/Button"; // Avoid this!
|
|
|
1336
1543
|
```
|
|
1337
1544
|
|
|
1338
1545
|
**Default Module Folders:**
|
|
1339
|
-
`apis`, `assets`, `atoms`, `components`, `constants`, `contexts`, `data`, `hooks`, `layouts`, `middlewares`, `providers`, `redux`, `requests`, `routes`, `schemas`, `services`, `styles`, `theme`, `utils`, `views`
|
|
1546
|
+
`actions`, `apis`, `assets`, `atoms`, `components`, `constants`, `contexts`, `data`, `enums`, `hooks`, `interfaces`, `layouts`, `middlewares`, `providers`, `reducers`, `redux`, `requests`, `routes`, `schemas`, `services`, `store`, `styles`, `theme`, `thunks`, `types`, `utils`, `views`
|
|
1340
1547
|
|
|
1341
1548
|
**Default Ignore Patterns:**
|
|
1342
1549
|
`index.js`, `index.jsx`, `index.ts`, `index.tsx`, `.DS_Store`, `__tests__`, `__mocks__`, `*.test.js`, `*.test.jsx`, `*.test.ts`, `*.test.tsx`, `*.spec.js`, `*.spec.jsx`, `*.spec.ts`, `*.spec.tsx`
|
|
@@ -1642,339 +1849,69 @@ function Card() {
|
|
|
1642
1849
|
</Content>
|
|
1643
1850
|
)}
|
|
1644
1851
|
|
|
1645
|
-
// ✅ Good — one simple, one complex
|
|
1646
|
-
{isLoading ? <Spinner /> : (
|
|
1647
|
-
<Content>
|
|
1648
|
-
<Header />
|
|
1649
|
-
<Body />
|
|
1650
|
-
</Content>
|
|
1651
|
-
)}
|
|
1652
|
-
|
|
1653
|
-
// ❌ Bad — awkward line breaks
|
|
1654
|
-
{isLoading
|
|
1655
|
-
? <Spinner />
|
|
1656
|
-
: <Content />}
|
|
1657
|
-
|
|
1658
|
-
// ❌ Bad — missing parentheses for complex branch
|
|
1659
|
-
{isLoading ? <Spinner /> : <Content>
|
|
1660
|
-
<Header />
|
|
1661
|
-
<Body />
|
|
1662
|
-
</Content>}
|
|
1663
|
-
```
|
|
1664
|
-
|
|
1665
|
-
---
|
|
1666
|
-
|
|
1667
|
-
### `no-empty-lines-in-jsx`
|
|
1668
|
-
|
|
1669
|
-
**What it does:** Removes empty lines inside JSX elements — between children and after opening/before closing tags.
|
|
1670
|
-
|
|
1671
|
-
**Why use it:** Empty lines inside JSX create visual gaps that break the component's visual structure.
|
|
1672
|
-
|
|
1673
|
-
```javascript
|
|
1674
|
-
// ✅ Good — no empty lines inside
|
|
1675
|
-
<div>
|
|
1676
|
-
<Header />
|
|
1677
|
-
<Content />
|
|
1678
|
-
<Footer />
|
|
1679
|
-
</div>
|
|
1680
|
-
|
|
1681
|
-
<Form>
|
|
1682
|
-
<Input name="email" />
|
|
1683
|
-
<Input name="password" />
|
|
1684
|
-
<Button>Submit</Button>
|
|
1685
|
-
</Form>
|
|
1686
|
-
|
|
1687
|
-
// ❌ Bad — empty line after opening tag
|
|
1688
|
-
<div>
|
|
1689
|
-
|
|
1690
|
-
<Header />
|
|
1691
|
-
<Content />
|
|
1692
|
-
</div>
|
|
1693
|
-
|
|
1694
|
-
// ❌ Bad — empty lines between children
|
|
1695
|
-
<Form>
|
|
1696
|
-
<Input name="email" />
|
|
1697
|
-
|
|
1698
|
-
<Input name="password" />
|
|
1699
|
-
|
|
1700
|
-
<Button>Submit</Button>
|
|
1701
|
-
</Form>
|
|
1702
|
-
|
|
1703
|
-
// ❌ Bad — empty line before closing tag
|
|
1704
|
-
<div>
|
|
1705
|
-
<Content />
|
|
1706
|
-
|
|
1707
|
-
</div>
|
|
1708
|
-
```
|
|
1709
|
-
|
|
1710
|
-
<br />
|
|
1711
|
-
|
|
1712
|
-
## 📞 Call Expression Rules
|
|
1713
|
-
|
|
1714
|
-
### `function-arguments-format`
|
|
1715
|
-
|
|
1716
|
-
**What it does:** Enforces consistent formatting for function call arguments:
|
|
1717
|
-
- Single simple argument stays on one line
|
|
1718
|
-
- 2+ arguments get one per line
|
|
1719
|
-
- Multiline arguments trigger full expansion
|
|
1720
|
-
- React hooks are skipped by default (they have their own rule)
|
|
1721
|
-
|
|
1722
|
-
**Why use it:** Consistent argument formatting makes function calls scannable and diffs clean when adding/removing arguments.
|
|
1723
|
-
|
|
1724
|
-
```javascript
|
|
1725
|
-
// ✅ Good — single argument stays compact
|
|
1726
|
-
fetchUser(userId);
|
|
1727
|
-
console.log(message);
|
|
1728
|
-
dispatch(action);
|
|
1729
|
-
|
|
1730
|
-
// ✅ Good — 2+ arguments get one per line
|
|
1731
|
-
setValue(
|
|
1732
|
-
"email",
|
|
1733
|
-
"user@example.com",
|
|
1734
|
-
);
|
|
1735
|
-
|
|
1736
|
-
createUser(
|
|
1737
|
-
name,
|
|
1738
|
-
email,
|
|
1739
|
-
password,
|
|
1740
|
-
);
|
|
1741
|
-
|
|
1742
|
-
// ✅ Good — multiline argument triggers expansion
|
|
1743
|
-
processData(
|
|
1744
|
-
{
|
|
1745
|
-
id: 1,
|
|
1746
|
-
name: "test",
|
|
1747
|
-
},
|
|
1748
|
-
);
|
|
1749
|
-
|
|
1750
|
-
// ✅ Good — callback with body triggers expansion
|
|
1751
|
-
items.forEach(
|
|
1752
|
-
(item) => {
|
|
1753
|
-
process(item);
|
|
1754
|
-
save(item);
|
|
1755
|
-
},
|
|
1756
|
-
);
|
|
1757
|
-
|
|
1758
|
-
// ❌ Bad — multiple arguments on same line
|
|
1759
|
-
setValue("email", "user@example.com");
|
|
1760
|
-
createUser(name, email, password);
|
|
1761
|
-
|
|
1762
|
-
// ❌ Bad — inconsistent formatting
|
|
1763
|
-
fn(arg1,
|
|
1764
|
-
arg2, arg3);
|
|
1765
|
-
```
|
|
1766
|
-
|
|
1767
|
-
**Options:**
|
|
1768
|
-
|
|
1769
|
-
| Option | Type | Default | Description |
|
|
1770
|
-
|--------|------|---------|-------------|
|
|
1771
|
-
| `minArgs` | `integer` | `2` | Minimum arguments to enforce multiline |
|
|
1772
|
-
| `skipHooks` | `boolean` | `true` | Skip React hooks (useEffect, etc.) |
|
|
1773
|
-
| `skipSingleArg` | `boolean` | `true` | Skip calls with single complex argument |
|
|
1774
|
-
|
|
1775
|
-
```javascript
|
|
1776
|
-
// Example: Require multiline for 3+ arguments
|
|
1777
|
-
"code-style/function-arguments-format": ["error", { minArgs: 3 }]
|
|
1778
|
-
|
|
1779
|
-
// Example: Don't skip React hooks
|
|
1780
|
-
"code-style/function-arguments-format": ["error", { skipHooks: false }]
|
|
1781
|
-
```
|
|
1782
|
-
|
|
1783
|
-
---
|
|
1784
|
-
|
|
1785
|
-
### `nested-call-closing-brackets`
|
|
1786
|
-
|
|
1787
|
-
**What it does:** Ensures nested function calls (common in styled-components, HOCs) have closing brackets on the same line: `}));`
|
|
1788
|
-
|
|
1789
|
-
**Why use it:** Scattered closing brackets (`}\n);\n` ) waste vertical space and make it harder to see where expressions end.
|
|
1790
|
-
|
|
1791
|
-
```javascript
|
|
1792
|
-
// ✅ Good — closing brackets together
|
|
1793
|
-
const StyledCard = styled(Card)(({ theme }) => ({
|
|
1794
|
-
color: theme.palette.text.primary,
|
|
1795
|
-
padding: theme.spacing(2),
|
|
1796
|
-
}));
|
|
1797
|
-
|
|
1798
|
-
const StyledButton = styled("button")(({ theme }) => ({
|
|
1799
|
-
backgroundColor: theme.colors.primary,
|
|
1800
|
-
}));
|
|
1801
|
-
|
|
1802
|
-
// ✅ Good — multiple levels
|
|
1803
|
-
const Component = connect(
|
|
1804
|
-
mapStateToProps,
|
|
1805
|
-
mapDispatchToProps,
|
|
1806
|
-
)(withRouter(MyComponent));
|
|
1807
|
-
|
|
1808
|
-
// ❌ Bad — closing brackets scattered
|
|
1809
|
-
const StyledCard = styled(Card)(({ theme }) => ({
|
|
1810
|
-
color: theme.palette.text.primary,
|
|
1811
|
-
})
|
|
1812
|
-
);
|
|
1813
|
-
|
|
1814
|
-
// ❌ Bad — each bracket on its own line
|
|
1815
|
-
const StyledCard = styled(Card)(({ theme }) => ({
|
|
1816
|
-
color: theme.colors.primary,
|
|
1817
|
-
})
|
|
1818
|
-
)
|
|
1819
|
-
;
|
|
1820
|
-
```
|
|
1821
|
-
|
|
1822
|
-
---
|
|
1823
|
-
|
|
1824
|
-
### `no-empty-lines-in-function-calls`
|
|
1825
|
-
|
|
1826
|
-
**What it does:** Removes empty lines within function call argument lists — between arguments and after opening/before closing parentheses.
|
|
1827
|
-
|
|
1828
|
-
**Why use it:** Empty lines between arguments break visual grouping. Arguments should flow as a cohesive list.
|
|
1829
|
-
|
|
1830
|
-
```javascript
|
|
1831
|
-
// ✅ Good — no empty lines
|
|
1832
|
-
createUser(
|
|
1833
|
-
name,
|
|
1834
|
-
email,
|
|
1835
|
-
password,
|
|
1836
|
-
role,
|
|
1837
|
-
);
|
|
1838
|
-
|
|
1839
|
-
fetchData(
|
|
1840
|
-
url,
|
|
1841
|
-
{
|
|
1842
|
-
method: "POST",
|
|
1843
|
-
body: data,
|
|
1844
|
-
},
|
|
1845
|
-
);
|
|
1846
|
-
|
|
1847
|
-
// ❌ Bad — empty line between arguments
|
|
1848
|
-
createUser(
|
|
1849
|
-
name,
|
|
1850
|
-
|
|
1851
|
-
email,
|
|
1852
|
-
|
|
1853
|
-
password,
|
|
1854
|
-
);
|
|
1855
|
-
|
|
1856
|
-
// ❌ Bad — empty line after opening paren
|
|
1857
|
-
fetchData(
|
|
1858
|
-
|
|
1859
|
-
url,
|
|
1860
|
-
options,
|
|
1861
|
-
);
|
|
1862
|
-
|
|
1863
|
-
// ❌ Bad — empty line before closing paren
|
|
1864
|
-
fetchData(
|
|
1865
|
-
url,
|
|
1866
|
-
options,
|
|
1867
|
-
|
|
1868
|
-
);
|
|
1869
|
-
```
|
|
1870
|
-
|
|
1871
|
-
---
|
|
1872
|
-
|
|
1873
|
-
### `opening-brackets-same-line`
|
|
1874
|
-
|
|
1875
|
-
**What it does:** Ensures opening brackets (`{`, `[`, `(`) in function arguments stay on the same line as the function call.
|
|
1876
|
-
|
|
1877
|
-
**Why use it:** Opening brackets on new lines create unnecessary indentation and vertical space.
|
|
1878
|
-
|
|
1879
|
-
```javascript
|
|
1880
|
-
// ✅ Good — brackets on same line as call
|
|
1881
|
-
fn({ key: value });
|
|
1882
|
-
process([1, 2, 3]);
|
|
1883
|
-
items.map(({ id }) => id);
|
|
1884
|
-
configure({ debug: true });
|
|
1885
|
-
|
|
1886
|
-
// ✅ Good — multiline content is fine
|
|
1887
|
-
fn({
|
|
1888
|
-
key: value,
|
|
1889
|
-
other: data,
|
|
1890
|
-
});
|
|
1891
|
-
|
|
1892
|
-
items.map(({ id, name }) => (
|
|
1893
|
-
<Item key={id} name={name} />
|
|
1894
|
-
));
|
|
1895
|
-
|
|
1896
|
-
// ❌ Bad — opening bracket on new line
|
|
1897
|
-
fn(
|
|
1898
|
-
{ key: value }
|
|
1899
|
-
);
|
|
1900
|
-
|
|
1901
|
-
process(
|
|
1902
|
-
[1, 2, 3]
|
|
1903
|
-
);
|
|
1852
|
+
// ✅ Good — one simple, one complex
|
|
1853
|
+
{isLoading ? <Spinner /> : (
|
|
1854
|
+
<Content>
|
|
1855
|
+
<Header />
|
|
1856
|
+
<Body />
|
|
1857
|
+
</Content>
|
|
1858
|
+
)}
|
|
1904
1859
|
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1860
|
+
// ❌ Bad — awkward line breaks
|
|
1861
|
+
{isLoading
|
|
1862
|
+
? <Spinner />
|
|
1863
|
+
: <Content />}
|
|
1864
|
+
|
|
1865
|
+
// ❌ Bad — missing parentheses for complex branch
|
|
1866
|
+
{isLoading ? <Spinner /> : <Content>
|
|
1867
|
+
<Header />
|
|
1868
|
+
<Body />
|
|
1869
|
+
</Content>}
|
|
1908
1870
|
```
|
|
1909
1871
|
|
|
1910
1872
|
---
|
|
1911
1873
|
|
|
1912
|
-
### `
|
|
1874
|
+
### `no-empty-lines-in-jsx`
|
|
1913
1875
|
|
|
1914
|
-
**What it does:**
|
|
1876
|
+
**What it does:** Removes empty lines inside JSX elements — between children and after opening/before closing tags.
|
|
1915
1877
|
|
|
1916
|
-
**Why use it:**
|
|
1878
|
+
**Why use it:** Empty lines inside JSX create visual gaps that break the component's visual structure.
|
|
1917
1879
|
|
|
1918
1880
|
```javascript
|
|
1919
|
-
// ✅ Good —
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
// ✅ Good — complex callbacks stay multiline
|
|
1927
|
-
const Page = lazy(() => {
|
|
1928
|
-
console.log("Loading page");
|
|
1929
|
-
return import("./Page");
|
|
1930
|
-
});
|
|
1931
|
-
|
|
1932
|
-
// ❌ Bad — unnecessary multiline for simple pattern
|
|
1933
|
-
const Page = lazy(
|
|
1934
|
-
() => import("./Page"),
|
|
1935
|
-
);
|
|
1936
|
-
|
|
1937
|
-
setTimeout(
|
|
1938
|
-
() => callback(),
|
|
1939
|
-
100,
|
|
1940
|
-
);
|
|
1941
|
-
```
|
|
1942
|
-
|
|
1943
|
-
---
|
|
1881
|
+
// ✅ Good — no empty lines inside
|
|
1882
|
+
<div>
|
|
1883
|
+
<Header />
|
|
1884
|
+
<Content />
|
|
1885
|
+
<Footer />
|
|
1886
|
+
</div>
|
|
1944
1887
|
|
|
1945
|
-
|
|
1888
|
+
<Form>
|
|
1889
|
+
<Input name="email" />
|
|
1890
|
+
<Input name="password" />
|
|
1891
|
+
<Button>Submit</Button>
|
|
1892
|
+
</Form>
|
|
1946
1893
|
|
|
1947
|
-
|
|
1894
|
+
// ❌ Bad — empty line after opening tag
|
|
1895
|
+
<div>
|
|
1948
1896
|
|
|
1949
|
-
|
|
1897
|
+
<Header />
|
|
1898
|
+
<Content />
|
|
1899
|
+
</div>
|
|
1950
1900
|
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
console.log(message);
|
|
1955
|
-
process(data.items);
|
|
1956
|
-
dispatch(action);
|
|
1957
|
-
setValue("key");
|
|
1958
|
-
getElement(document.body);
|
|
1901
|
+
// ❌ Bad — empty lines between children
|
|
1902
|
+
<Form>
|
|
1903
|
+
<Input name="email" />
|
|
1959
1904
|
|
|
1960
|
-
|
|
1961
|
-
processConfig({
|
|
1962
|
-
key: value,
|
|
1963
|
-
other: data,
|
|
1964
|
-
});
|
|
1905
|
+
<Input name="password" />
|
|
1965
1906
|
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
userId,
|
|
1969
|
-
);
|
|
1907
|
+
<Button>Submit</Button>
|
|
1908
|
+
</Form>
|
|
1970
1909
|
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1910
|
+
// ❌ Bad — empty line before closing tag
|
|
1911
|
+
<div>
|
|
1912
|
+
<Content />
|
|
1974
1913
|
|
|
1975
|
-
|
|
1976
|
-
action,
|
|
1977
|
-
);
|
|
1914
|
+
</div>
|
|
1978
1915
|
```
|
|
1979
1916
|
|
|
1980
1917
|
<br />
|
|
@@ -2200,6 +2137,267 @@ const styles = {
|
|
|
2200
2137
|
|
|
2201
2138
|
<br />
|
|
2202
2139
|
|
|
2140
|
+
## 📐 Spacing Rules
|
|
2141
|
+
|
|
2142
|
+
### `assignment-value-same-line`
|
|
2143
|
+
|
|
2144
|
+
**What it does:** Ensures the assigned value starts on the same line as the `=` sign, not on a new line.
|
|
2145
|
+
|
|
2146
|
+
**Why use it:** Breaking after `=` creates awkward formatting and wastes vertical space. Keeping values on the same line as `=` is more readable.
|
|
2147
|
+
|
|
2148
|
+
```javascript
|
|
2149
|
+
// ✅ Good — value starts on same line as =
|
|
2150
|
+
const name = "John";
|
|
2151
|
+
const config = {
|
|
2152
|
+
host: "localhost",
|
|
2153
|
+
port: 3000,
|
|
2154
|
+
};
|
|
2155
|
+
const items = [
|
|
2156
|
+
"first",
|
|
2157
|
+
"second",
|
|
2158
|
+
];
|
|
2159
|
+
|
|
2160
|
+
// ❌ Bad — value on new line after =
|
|
2161
|
+
const name =
|
|
2162
|
+
"John";
|
|
2163
|
+
const config =
|
|
2164
|
+
{
|
|
2165
|
+
host: "localhost",
|
|
2166
|
+
port: 3000,
|
|
2167
|
+
};
|
|
2168
|
+
const items =
|
|
2169
|
+
[
|
|
2170
|
+
"first",
|
|
2171
|
+
"second",
|
|
2172
|
+
];
|
|
2173
|
+
```
|
|
2174
|
+
|
|
2175
|
+
---
|
|
2176
|
+
|
|
2177
|
+
### `member-expression-bracket-spacing`
|
|
2178
|
+
|
|
2179
|
+
**What it does:** Removes spaces inside brackets in computed member expressions (array access, dynamic property access).
|
|
2180
|
+
|
|
2181
|
+
**Why use it:** Consistent with JavaScript conventions. Spaces inside brackets look inconsistent with array literals and other bracket usage.
|
|
2182
|
+
|
|
2183
|
+
```javascript
|
|
2184
|
+
// ✅ Good — no spaces inside brackets
|
|
2185
|
+
const value = arr[0];
|
|
2186
|
+
const name = obj[key];
|
|
2187
|
+
const item = data[index];
|
|
2188
|
+
const nested = matrix[row][col];
|
|
2189
|
+
|
|
2190
|
+
// ❌ Bad — spaces inside brackets
|
|
2191
|
+
const value = arr[ 0 ];
|
|
2192
|
+
const name = obj[ key ];
|
|
2193
|
+
const item = data[ index ];
|
|
2194
|
+
```
|
|
2195
|
+
|
|
2196
|
+
<br />
|
|
2197
|
+
|
|
2198
|
+
## 🔷 TypeScript Rules
|
|
2199
|
+
|
|
2200
|
+
### `enum-format`
|
|
2201
|
+
|
|
2202
|
+
**What it does:** Enforces consistent formatting for TypeScript enums:
|
|
2203
|
+
- Enum names must be PascalCase and end with `Enum` suffix
|
|
2204
|
+
- Enum members must be UPPER_CASE (for string enums) or PascalCase (for numeric enums)
|
|
2205
|
+
- No empty lines between enum members
|
|
2206
|
+
- Members must end with commas, not semicolons
|
|
2207
|
+
|
|
2208
|
+
**Why use it:** Consistent enum naming makes enums instantly recognizable. UPPER_CASE members follow common conventions for constants.
|
|
2209
|
+
|
|
2210
|
+
```typescript
|
|
2211
|
+
// ✅ Good — proper enum format
|
|
2212
|
+
export enum StatusEnum {
|
|
2213
|
+
ACTIVE = "active",
|
|
2214
|
+
INACTIVE = "inactive",
|
|
2215
|
+
PENDING = "pending",
|
|
2216
|
+
}
|
|
2217
|
+
|
|
2218
|
+
export enum HttpMethodEnum {
|
|
2219
|
+
DELETE = "DELETE",
|
|
2220
|
+
GET = "GET",
|
|
2221
|
+
POST = "POST",
|
|
2222
|
+
PUT = "PUT",
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
// ❌ Bad — wrong naming
|
|
2226
|
+
export enum Status { // Missing Enum suffix
|
|
2227
|
+
active = "active", // Should be UPPER_CASE
|
|
2228
|
+
inactive = "inactive"; // Should use comma, not semicolon
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2231
|
+
// ❌ Bad — empty lines between members
|
|
2232
|
+
export enum UserStatusEnum {
|
|
2233
|
+
ACTIVE = "active",
|
|
2234
|
+
|
|
2235
|
+
INACTIVE = "inactive",
|
|
2236
|
+
}
|
|
2237
|
+
```
|
|
2238
|
+
|
|
2239
|
+
---
|
|
2240
|
+
|
|
2241
|
+
### `interface-format`
|
|
2242
|
+
|
|
2243
|
+
**What it does:** Enforces consistent formatting for TypeScript interfaces:
|
|
2244
|
+
- Interface names must be PascalCase and end with `Interface` suffix
|
|
2245
|
+
- Properties must be camelCase
|
|
2246
|
+
- No empty lines between properties
|
|
2247
|
+
- Properties must end with commas, not semicolons
|
|
2248
|
+
|
|
2249
|
+
**Why use it:** Consistent interface naming makes interfaces instantly recognizable. The suffix clearly distinguishes interfaces from types and classes.
|
|
2250
|
+
|
|
2251
|
+
```typescript
|
|
2252
|
+
// ✅ Good — proper interface format
|
|
2253
|
+
export interface UserInterface {
|
|
2254
|
+
email: string,
|
|
2255
|
+
id: string,
|
|
2256
|
+
isActive: boolean,
|
|
2257
|
+
name: string,
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2260
|
+
export interface ApiResponseInterface<T> {
|
|
2261
|
+
data: T,
|
|
2262
|
+
error: string | null,
|
|
2263
|
+
status: number,
|
|
2264
|
+
success: boolean,
|
|
2265
|
+
}
|
|
2266
|
+
|
|
2267
|
+
// ❌ Bad — wrong naming
|
|
2268
|
+
export interface User { // Missing Interface suffix
|
|
2269
|
+
Email: string; // Should be camelCase
|
|
2270
|
+
ID: string; // Should be camelCase
|
|
2271
|
+
is_active: boolean; // Should be camelCase, use comma
|
|
2272
|
+
}
|
|
2273
|
+
|
|
2274
|
+
// ❌ Bad — semicolons and empty lines
|
|
2275
|
+
export interface UserInterface {
|
|
2276
|
+
email: string; // Should use comma
|
|
2277
|
+
|
|
2278
|
+
name: string; // Empty line not allowed
|
|
2279
|
+
}
|
|
2280
|
+
```
|
|
2281
|
+
|
|
2282
|
+
---
|
|
2283
|
+
|
|
2284
|
+
### `type-format`
|
|
2285
|
+
|
|
2286
|
+
**What it does:** Enforces consistent formatting for TypeScript type aliases:
|
|
2287
|
+
- Type names must be PascalCase and end with `Type` suffix
|
|
2288
|
+
- Properties must be camelCase
|
|
2289
|
+
- No empty lines between properties
|
|
2290
|
+
- Properties must end with commas, not semicolons
|
|
2291
|
+
|
|
2292
|
+
**Why use it:** Consistent type naming makes types instantly recognizable. The suffix clearly distinguishes types from interfaces and classes.
|
|
2293
|
+
|
|
2294
|
+
```typescript
|
|
2295
|
+
// ✅ Good — proper type format
|
|
2296
|
+
export type UserType = {
|
|
2297
|
+
email: string,
|
|
2298
|
+
id: string,
|
|
2299
|
+
name: string,
|
|
2300
|
+
};
|
|
2301
|
+
|
|
2302
|
+
export type ApiResponseType<T> = {
|
|
2303
|
+
data: T,
|
|
2304
|
+
error: string | null,
|
|
2305
|
+
status: number,
|
|
2306
|
+
};
|
|
2307
|
+
|
|
2308
|
+
// ❌ Bad — wrong naming
|
|
2309
|
+
export type User = { // Missing Type suffix
|
|
2310
|
+
Email: string; // Should be camelCase
|
|
2311
|
+
ID: string; // Should use comma
|
|
2312
|
+
};
|
|
2313
|
+
|
|
2314
|
+
// ❌ Bad — empty lines
|
|
2315
|
+
export type ConfigType = {
|
|
2316
|
+
debug: boolean,
|
|
2317
|
+
|
|
2318
|
+
port: number, // Empty line not allowed
|
|
2319
|
+
};
|
|
2320
|
+
```
|
|
2321
|
+
|
|
2322
|
+
---
|
|
2323
|
+
|
|
2324
|
+
### `typescript-definition-location`
|
|
2325
|
+
|
|
2326
|
+
**What it does:** Enforces that TypeScript definitions are placed in their designated folders:
|
|
2327
|
+
- Interfaces must be in files inside the `interfaces` folder
|
|
2328
|
+
- Types must be in files inside the `types` folder
|
|
2329
|
+
- Enums must be in files inside the `enums` folder
|
|
2330
|
+
|
|
2331
|
+
**Why use it:** Separating type definitions by category makes them easier to find, maintain, and share across the codebase. It promotes a clean and organized project structure.
|
|
2332
|
+
|
|
2333
|
+
```typescript
|
|
2334
|
+
// ✅ Good — definitions in correct folders
|
|
2335
|
+
// src/interfaces/user.ts
|
|
2336
|
+
export interface UserInterface {
|
|
2337
|
+
id: string,
|
|
2338
|
+
name: string,
|
|
2339
|
+
}
|
|
2340
|
+
|
|
2341
|
+
// src/types/config.ts
|
|
2342
|
+
export type ConfigType = {
|
|
2343
|
+
apiUrl: string,
|
|
2344
|
+
timeout: number,
|
|
2345
|
+
};
|
|
2346
|
+
|
|
2347
|
+
// src/enums/status.ts
|
|
2348
|
+
export enum UserRoleEnum {
|
|
2349
|
+
ADMIN = "admin",
|
|
2350
|
+
USER = "user",
|
|
2351
|
+
}
|
|
2352
|
+
|
|
2353
|
+
// ❌ Bad — definitions in wrong folders
|
|
2354
|
+
// src/components/user-card.tsx
|
|
2355
|
+
interface UserProps { // Should be in interfaces folder
|
|
2356
|
+
name: string,
|
|
2357
|
+
}
|
|
2358
|
+
|
|
2359
|
+
// src/types/user.ts
|
|
2360
|
+
export interface UserInterface { // Should be in interfaces folder, not types
|
|
2361
|
+
id: string,
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2364
|
+
export enum StatusEnum { // Should be in enums folder, not types
|
|
2365
|
+
ACTIVE = "active",
|
|
2366
|
+
}
|
|
2367
|
+
```
|
|
2368
|
+
|
|
2369
|
+
<br />
|
|
2370
|
+
|
|
2371
|
+
## 📝 Variable Rules
|
|
2372
|
+
|
|
2373
|
+
### `variable-naming-convention`
|
|
2374
|
+
|
|
2375
|
+
**What it does:** Enforces naming conventions for variables:
|
|
2376
|
+
- **camelCase** for regular variables and functions
|
|
2377
|
+
- **UPPER_CASE** for constants (primitive values)
|
|
2378
|
+
- **PascalCase** for React components and classes
|
|
2379
|
+
- **camelCase with `use` prefix** for hooks
|
|
2380
|
+
|
|
2381
|
+
**Why use it:** Consistent naming makes code predictable. You can tell what something is by how it's named.
|
|
2382
|
+
|
|
2383
|
+
```javascript
|
|
2384
|
+
// ✅ Good — correct conventions
|
|
2385
|
+
const userName = "John"; // camelCase for variables
|
|
2386
|
+
const itemCount = 42; // camelCase for variables
|
|
2387
|
+
const MAX_RETRIES = 3; // UPPER_CASE for constants
|
|
2388
|
+
const API_BASE_URL = "/api"; // UPPER_CASE for constants
|
|
2389
|
+
const UserProfile = () => <div />; // PascalCase for components
|
|
2390
|
+
const useAuth = () => {}; // camelCase with use prefix for hooks
|
|
2391
|
+
|
|
2392
|
+
// ❌ Bad — wrong conventions
|
|
2393
|
+
const user_name = "John"; // snake_case
|
|
2394
|
+
const maxretries = 3; // should be UPPER_CASE
|
|
2395
|
+
const userProfile = () => <div />; // should be PascalCase
|
|
2396
|
+
const UseAuth = () => {}; // hooks should be camelCase
|
|
2397
|
+
```
|
|
2398
|
+
|
|
2399
|
+
<br />
|
|
2400
|
+
|
|
2203
2401
|
---
|
|
2204
2402
|
|
|
2205
2403
|
## 🔧 Auto-fixing
|