Skip to content

Commit 98fb997

Browse files
committed
Minor changes to #71 to fix tests, remove esquery selectors for perf.
1 parent e918029 commit 98fb997

File tree

2 files changed

+32
-27
lines changed

2 files changed

+32
-27
lines changed

src/rules/prefer-for.ts

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -48,32 +48,36 @@ const rule: TSESLint.RuleModule<"preferFor" | "preferForOrIndex", []> = {
4848
});
4949
};
5050

51-
const report = (node: T.CallExpression) => {
52-
if (
53-
node.callee.type === "MemberExpression" &&
54-
getPropertyName(node.callee) === "map" &&
55-
node.arguments.length === 1 && // passing thisArg to Array.prototype.map is rare, deopt in that case
56-
isFunctionNode(node.arguments[0])
57-
) {
58-
const mapFnNode = node.arguments[0];
59-
if (mapFnNode.params.length === 1 && mapFnNode.params[0].type !== "RestElement") {
60-
// The map fn doesn't take an index param, so it can't possibly be an index-keyed list. Use <For />.
61-
// The returned JSX, if it's coming from React, will have an unnecessary `key` prop to be removed in
62-
// the useless-keys rule.
63-
reportPreferFor(node);
64-
} else {
65-
// Too many possible solutions to make a suggestion or fix
66-
context.report({
67-
node,
68-
messageId: "preferForOrIndex",
69-
});
70-
}
71-
}
72-
};
73-
7451
return {
75-
"JSXElement > JSXExpressionContainer > CallExpression": report,
76-
"JSXElement > JSXExpressionContainer > ChainExpression > CallExpression": report,
52+
CallExpression(node) {
53+
const callOrChain = node.parent?.type === "ChainExpression" ? node.parent : node;
54+
if (
55+
callOrChain.parent?.type === "JSXExpressionContainer" &&
56+
callOrChain.parent.parent?.type === "JSXElement"
57+
) {
58+
// check for Array.prototype.map in JSX
59+
if (
60+
node.callee.type === "MemberExpression" &&
61+
getPropertyName(node.callee) === "map" &&
62+
node.arguments.length === 1 && // passing thisArg to Array.prototype.map is rare, deopt in that case
63+
isFunctionNode(node.arguments[0])
64+
) {
65+
const mapFnNode = node.arguments[0];
66+
if (mapFnNode.params.length === 1 && mapFnNode.params[0].type !== "RestElement") {
67+
// The map fn doesn't take an index param, so it can't possibly be an index-keyed list. Use <For />.
68+
// The returned JSX, if it's coming from React, will have an unnecessary `key` prop to be removed in
69+
// the useless-keys rule.
70+
reportPreferFor(node);
71+
} else {
72+
// Too many possible solutions to make a suggestion or fix
73+
context.report({
74+
node,
75+
messageId: "preferForOrIndex",
76+
});
77+
}
78+
}
79+
}
80+
},
7781
};
7882
},
7983
};

test/rules/prefer-for.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { run } from "../ruleTester";
1+
import { run, tsOnlyTest } from "../ruleTester";
22
import rule from "../../src/rules/prefer-for";
33

44
export const cases = run("prefer-for", rule, {
@@ -41,8 +41,9 @@ export const cases = run("prefer-for", rule, {
4141
errors: [{ messageId: "preferFor" }],
4242
output: `
4343
function Component(props) {
44-
return <ol>{<For each={props.data}>{(d) => <li>{d.text}</li>}</For>}</ol>;
44+
return <ol>{<For each={props.data}>{d => <li>{d.text}</li>}</For>}</ol>;
4545
}`,
46+
...tsOnlyTest,
4647
},
4748
// deopts
4849
{

0 commit comments

Comments
 (0)