$npx -y skills add gaia-react/gaia --skill eslint-fixesResolve specific ESLint errors and warnings that appear in this project. Use when fixing lint failures, ESLint reported issues, or autofix conflicts (e.g. no-void, canonical/export-specifier-newline vs prettier, no-shadow trailing underscores, sonarjs/deprecation, you-dont-need-l
| 1 | # ESLint Fix Patterns |
| 2 | |
| 3 | How to resolve specific ESLint errors in this project. |
| 4 | |
| 5 | ## no-void |
| 6 | |
| 7 | Don't use the `void` operator in event listener functions. Instead, make the function `async` and `await` the promise. |
| 8 | |
| 9 | ```tsx |
| 10 | // BAD |
| 11 | const handleClickNavigate = () => { |
| 12 | void navigate('/path'); |
| 13 | }; |
| 14 | |
| 15 | // GOOD |
| 16 | const handleClickNavigate = async () => { |
| 17 | await navigate('/path'); |
| 18 | }; |
| 19 | ``` |
| 20 | |
| 21 | ## canonical/export-specifier-newline vs prettier conflict |
| 22 | |
| 23 | Use inline `export const` declarations instead of a grouped `export { ... }` statement to avoid circular fix warnings between these two rules. |
| 24 | |
| 25 | ```tsx |
| 26 | // BAD, causes circular fix between prettier and canonical |
| 27 | export {DAYS, DURATIONS, FITNESS_GOALS}; |
| 28 | |
| 29 | // GOOD, declare with export directly |
| 30 | export const DAYS = ['mon', 'tue'] as const; |
| 31 | export const DURATIONS = [15, 30, 45] as const; |
| 32 | export const FITNESS_GOALS = ['weight_loss'] as const; |
| 33 | ``` |
| 34 | |
| 35 | ## no-shadow trailing underscores |
| 36 | |
| 37 | ESLint's `no-shadow` autofixes by appending `_`. Once shadowing is resolved, remove the trailing `_`. |
| 38 | |
| 39 | ## sonarjs/deprecation |
| 40 | |
| 41 | Never suppress with `eslint-disable`. Always fix the underlying deprecation. |
| 42 | |
| 43 | Common case: Zod v4 deprecated `z.string().email()` in favor of `z.email()`. |
| 44 | |
| 45 | ```tsx |
| 46 | // BAD, suppressing the warning |
| 47 | // eslint-disable-next-line sonarjs/deprecation |
| 48 | email: z.string().email(), |
| 49 | |
| 50 | // GOOD, use the non-deprecated API |
| 51 | email: z.email(), |
| 52 | ``` |
| 53 | |
| 54 | ## you-dont-need-lodash-underscore/\* |
| 55 | |
| 56 | Use native JavaScript instead of lodash/underscore equivalents. |
| 57 | |
| 58 | ```tsx |
| 59 | // BAD |
| 60 | import _ from 'lodash'; |
| 61 | const first = _.find(items, (item) => item.active); |
| 62 | const names = _.map(items, (item) => item.name); |
| 63 | |
| 64 | // GOOD |
| 65 | const first = items.find((item) => item.active); |
| 66 | const names = items.map((item) => item.name); |
| 67 | ``` |
| 68 | |
| 69 | ## testing-library/prefer-screen-queries |
| 70 | |
| 71 | Use `screen` queries instead of destructuring from `render()`. |
| 72 | |
| 73 | ```tsx |
| 74 | // BAD |
| 75 | const {getByText, getByRole} = render(<MyComponent />); |
| 76 | |
| 77 | // GOOD |
| 78 | render(<MyComponent />); |
| 79 | screen.getByText('...'); |
| 80 | screen.getByRole('button'); |
| 81 | ``` |
| 82 | |
| 83 | ## testing-library/await-async-events |
| 84 | |
| 85 | `userEvent` methods are async, always `await` them. |
| 86 | |
| 87 | ```tsx |
| 88 | // BAD |
| 89 | userEvent.click(button); |
| 90 | |
| 91 | // GOOD |
| 92 | await userEvent.click(button); |
| 93 | ``` |
| 94 | |
| 95 | ## jest-dom/prefer-\* |
| 96 | |
| 97 | Use jest-dom matchers instead of raw DOM property checks. |
| 98 | |
| 99 | ```tsx |
| 100 | // BAD |
| 101 | expect(input.value).toBe('hello'); |
| 102 | expect(checkbox.checked).toBe(true); |
| 103 | expect(el.textContent).toBe('Hello'); |
| 104 | |
| 105 | // GOOD |
| 106 | expect(input).toHaveValue('hello'); |
| 107 | expect(checkbox).toBeChecked(); |
| 108 | expect(el).toHaveTextContent('Hello'); |
| 109 | ``` |