Skip to content

Commit c316f48

Browse files
committed
refactor: minor improvements
1 parent 198c728 commit c316f48

File tree

11 files changed

+92
-35
lines changed

11 files changed

+92
-35
lines changed

.pkgs/configs/eslint.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export const typescript = tseslint.config({
7474
"@typescript-eslint/consistent-type-exports": "error",
7575
"@typescript-eslint/consistent-type-imports": "error",
7676
"@typescript-eslint/explicit-function-return-type": "off",
77+
"@typescript-eslint/no-confusing-void-expression": "off",
7778
"@typescript-eslint/no-empty-object-type": "off",
7879
"@typescript-eslint/no-misused-promises": "warn",
7980
"@typescript-eslint/no-namespace": "off",

.pkgs/configs/eslint.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export const typescript: ConfigArray = tseslint.config(
8585
"@typescript-eslint/consistent-type-exports": "error",
8686
"@typescript-eslint/consistent-type-imports": "error",
8787
"@typescript-eslint/explicit-function-return-type": "off",
88+
"@typescript-eslint/no-confusing-void-expression": "off",
8889
"@typescript-eslint/no-empty-object-type": "off",
8990
"@typescript-eslint/no-misused-promises": "warn",
9091
"@typescript-eslint/no-namespace": "off",

eslint.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import url from "node:url";
33
import markdown from "@eslint/markdown";
44
import * as configs from "@local/configs/eslint";
55
import pluginLocal from "@local/eslint-plugin-local";
6+
import { globalIgnores } from "eslint/config";
67
import configFlatGitignore from "eslint-config-flat-gitignore";
78
import pluginVitest from "eslint-plugin-vitest";
89
import tseslint from "typescript-eslint";
@@ -34,7 +35,7 @@ const packagesTsConfigs = [
3435
];
3536

3637
export default tseslint.config(
37-
{ ignores: GLOB_IGNORES },
38+
globalIgnores(GLOB_IGNORES),
3839
{
3940
extends: [
4041
markdown.configs.recommended,

packages/plugins/eslint-plugin-react-x/src/rules/no-array-index-key.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as AST from "@eslint-react/ast";
22
import { isCloneElementCall, isCreateElementCall, isInitializedFromReact } from "@eslint-react/core";
33
import { _ } from "@eslint-react/eff";
44
import type { RuleContext, RuleFeature } from "@eslint-react/shared";
5-
import { unsafeDecodeSettings } from "@eslint-react/shared";
5+
import { report, unsafeDecodeSettings } from "@eslint-react/shared";
66
import { AST_NODE_TYPES as T } from "@typescript-eslint/types";
77
import type { TSESTree } from "@typescript-eslint/utils";
88
import type { ReportDescriptor, RuleListener } from "@typescript-eslint/utils/ts-eslint";
@@ -218,10 +218,8 @@ export function create(context: RuleContext<MessageID, []>): RuleListener {
218218
if (!("value" in prop)) {
219219
continue;
220220
}
221-
const descriptors = getReportDescriptors(prop.value);
222-
for (const descriptor of descriptors) {
223-
context.report(descriptor);
224-
}
221+
getReportDescriptors(prop.value)
222+
.map(report(context));
225223
}
226224
},
227225
"CallExpression:exit"() {
@@ -237,10 +235,8 @@ export function create(context: RuleContext<MessageID, []>): RuleListener {
237235
if (node.value?.type !== T.JSXExpressionContainer) {
238236
return;
239237
}
240-
const descriptors = getReportDescriptors(node.value.expression);
241-
for (const descriptor of descriptors) {
242-
context.report(descriptor);
243-
}
238+
getReportDescriptors(node.value.expression)
239+
.map(report(context));
244240
},
245241
};
246242
}

packages/plugins/eslint-plugin-react-x/src/rules/no-leaked-conditional-rendering.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as AST from "@eslint-react/ast";
2-
import { _, identity } from "@eslint-react/eff";
2+
import { _, flow, identity } from "@eslint-react/eff";
33
import type { RuleContext, RuleFeature } from "@eslint-react/shared";
4-
import { getSettingsFromContext } from "@eslint-react/shared";
4+
import { getSettingsFromContext, report } from "@eslint-react/shared";
55
import * as VAR from "@eslint-react/var";
66
import { getConstrainedTypeAtLocation } from "@typescript-eslint/type-utils";
77
import type { TSESTree } from "@typescript-eslint/types";
@@ -261,11 +261,7 @@ export function create(context: RuleContext<MessageID, []>): RuleListener {
261261
})
262262
.otherwise(() => _);
263263
}
264-
const visitorFunction = (node: TSESTree.Expression) => {
265-
const descriptor = getReportDescriptor(node);
266-
if (descriptor == null) return;
267-
context.report(descriptor);
268-
};
264+
const visitorFunction = flow(getReportDescriptor, report(context));
269265
return {
270266
"JSXExpressionContainer > ConditionalExpression": visitorFunction,
271267
"JSXExpressionContainer > LogicalExpression": visitorFunction,

packages/plugins/eslint-plugin-react-x/src/rules/no-missing-key.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,28 @@ ruleTester.run(RULE_NAME, rule, {
188188
},
189189
],
190190
},
191+
// TODO: Fix this test case
192+
// {
193+
// code: tsx`
194+
// const CustomDescription = (props: CustomDescriptionProps) => {
195+
// const { items } = props;
196+
197+
// const newItems = items.map((item) => {
198+
// const label = <div>{item.label}</div>;
199+
200+
// return { label, children: item.children };
201+
202+
// // This one works without any error
203+
// return { label: <div>{item.label}</div>, children: item.children };
204+
// });
205+
206+
// return <Descriptions items={newItems} />;
207+
// };
208+
// `,
209+
// errors: [
210+
// { messageId: "missingKey" },
211+
// ],
212+
// },
191213
],
192214
valid: [
193215
...allValid,

packages/plugins/eslint-plugin-react-x/src/rules/no-missing-key.ts

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as AST from "@eslint-react/ast";
22
import { isChildrenToArrayCall } from "@eslint-react/core";
33
import * as JSX from "@eslint-react/jsx";
4-
import type { RuleContext, RuleFeature } from "@eslint-react/shared";
4+
import { report, type RuleContext, type RuleFeature } from "@eslint-react/shared";
55
import type { TSESTree } from "@typescript-eslint/types";
66
import { AST_NODE_TYPES as T } from "@typescript-eslint/types";
77
import type { ReportDescriptor, RuleListener } from "@typescript-eslint/utils/ts-eslint";
@@ -38,6 +38,7 @@ export default createRule<[], MessageID>({
3838

3939
export function create(context: RuleContext<MessageID, []>): RuleListener {
4040
const state = { isWithinChildrenToArray: false };
41+
4142
function checkIteratorElement(node: TSESTree.Node): null | ReportDescriptor<MessageID> {
4243
switch (node.type) {
4344
case T.JSXElement: {
@@ -84,13 +85,9 @@ export function create(context: RuleContext<MessageID, []>): RuleListener {
8485
function checkBlockStatement(node: TSESTree.BlockStatement) {
8586
const descriptors: ReportDescriptor<MessageID>[] = [];
8687
for (const statement of AST.getNestedReturnStatements(node)) {
87-
if (statement.argument == null) {
88-
continue;
89-
}
88+
if (statement.argument == null) continue;
9089
const descriptor = checkIteratorElement(statement.argument);
91-
if (descriptor != null) {
92-
descriptors.push(descriptor);
93-
}
90+
if (descriptor != null) descriptors.push(descriptor);
9491
}
9592
return descriptors;
9693
}
@@ -107,7 +104,7 @@ export function create(context: RuleContext<MessageID, []>): RuleListener {
107104
const initialScope = context.sourceCode.getScope(node);
108105
for (const element of elements) {
109106
if (!JSX.hasAttribute("key", element.openingElement.attributes, initialScope)) {
110-
context.report({
107+
report(context)({
111108
messageId: "missingKey",
112109
node: element,
113110
});
@@ -119,24 +116,21 @@ export function create(context: RuleContext<MessageID, []>): RuleListener {
119116
if (state.isWithinChildrenToArray) {
120117
return;
121118
}
122-
const isMapCallLike = AST.isMapCallLoose(node);
123-
if (!isMapCallLike && !isArrayFromCall(node)) {
119+
const isMapCall = AST.isMapCallLoose(node);
120+
if (!isMapCall && !isArrayFromCall(node)) {
124121
return;
125122
}
126-
const fn = node.arguments[isMapCallLike ? 0 : 1];
127-
if (fn?.type !== T.ArrowFunctionExpression && fn?.type !== T.FunctionExpression) {
123+
const fn = node.arguments[isMapCall ? 0 : 1];
124+
if (!AST.isFunction(fn)) {
128125
return;
129126
}
130127
if (fn.body.type === T.BlockStatement) {
131128
for (const descriptor of checkBlockStatement(fn.body)) {
132-
context.report(descriptor);
129+
report(context)(descriptor);
133130
}
134131
return;
135132
}
136-
const descriptor = checkExpression(fn.body);
137-
if (descriptor != null) {
138-
context.report(descriptor);
139-
}
133+
report(context)(checkExpression(fn.body));
140134
},
141135
"CallExpression:exit"(node) {
142136
if (!isChildrenToArrayCall(context, node)) {
@@ -149,7 +143,7 @@ export function create(context: RuleContext<MessageID, []>): RuleListener {
149143
return;
150144
}
151145
if (node.parent.type === T.ArrayExpression) {
152-
context.report({
146+
report(context)({
153147
messageId: "unexpectedFragmentSyntax",
154148
node,
155149
});

packages/shared/docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,4 @@
4848
- [getSettingsFromContext](functions/getSettingsFromContext.md)
4949
- [isInEditorEnv](functions/isInEditorEnv.md)
5050
- [isInGitHooksOrLintStaged](functions/isInGitHooksOrLintStaged.md)
51+
- [report](functions/report.md)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
[**@eslint-react/shared**](../README.md)
2+
3+
***
4+
5+
[@eslint-react/shared](../README.md) / report
6+
7+
# Function: report()
8+
9+
> **report**\<`MessageID`\>(`context`): (`descriptor`) => `void`
10+
11+
## Type Parameters
12+
13+
### MessageID
14+
15+
`MessageID` *extends* `string`
16+
17+
## Parameters
18+
19+
### context
20+
21+
[`RuleContext`](../type-aliases/RuleContext.md)
22+
23+
## Returns
24+
25+
`Function`
26+
27+
### Parameters
28+
29+
#### descriptor
30+
31+
`undefined` | `null` | `ReportDescriptor`\<`MessageID`\>
32+
33+
### Returns
34+
35+
`void`

packages/shared/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export * from "./create-rule";
33
export * from "./env";
44
export * from "./get-id";
55
export * from "./get-react-version";
6+
export * from "./report";
67
export * from "./schemas";
78
export * from "./settings";
89
export type * from "./types";

0 commit comments

Comments
 (0)