Skip to content

Commit 423e249

Browse files
fix(prefer-tacit): handling functions that don't map to directly to an eslint node (#802)
Fix 801
1 parent 4558b4a commit 423e249

File tree

3 files changed

+43
-14
lines changed

3 files changed

+43
-14
lines changed

src/rules/prefer-tacit.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,17 @@ import { ruleNameScope } from "#eslint-plugin-functional/utils/misc";
1515
import { type ESFunction } from "#eslint-plugin-functional/utils/node-types";
1616
import {
1717
createRule,
18-
getESTreeNode,
1918
getTypeOfNode,
19+
getTypeOfTSNode,
2020
type NamedCreateRuleCustomMeta,
2121
type RuleResult,
2222
} from "#eslint-plugin-functional/utils/rule";
2323
import { isNested } from "#eslint-plugin-functional/utils/tree";
2424
import {
2525
isBlockStatement,
2626
isCallExpression,
27-
isDefined,
28-
isFunctionLike,
2927
isIdentifier,
3028
isReturnStatement,
31-
isTSFunctionType,
3229
} from "#eslint-plugin-functional/utils/type-guards";
3330

3431
/**
@@ -106,13 +103,12 @@ function isCallerViolation(
106103
if (tsDeclaration === undefined) {
107104
return false;
108105
}
109-
const declaration = getESTreeNode(tsDeclaration, context);
110106

111-
return (
112-
isDefined(declaration) &&
113-
(isFunctionLike(declaration) || isTSFunctionType(declaration)) &&
114-
declaration.params.length === caller.arguments.length
115-
);
107+
return getTypeOfTSNode(tsDeclaration, context)
108+
.getCallSignatures()
109+
.some(
110+
(signature) => signature.parameters.length === caller.arguments.length,
111+
);
116112
}
117113

118114
/**

src/utils/rule.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,22 @@ export function getTypeOfNode<Context extends RuleContext<string, BaseOptions>>(
188188
node: TSESTree.Node,
189189
context: Context,
190190
): Type {
191-
const parserServices = getParserServices(context);
191+
const { esTreeNodeToTSNodeMap } = getParserServices(context);
192192

193-
const checker = parserServices.program.getTypeChecker();
194-
const { esTreeNodeToTSNodeMap } = parserServices;
193+
const tsNode = esTreeNodeToTSNodeMap.get(node);
194+
return getTypeOfTSNode(tsNode, context);
195+
}
196+
197+
/**
198+
* Get the type of the the given ts node.
199+
*/
200+
export function getTypeOfTSNode<
201+
Context extends RuleContext<string, BaseOptions>,
202+
>(node: TSNode, context: Context): Type {
203+
const { program } = getParserServices(context);
204+
const checker = program.getTypeChecker();
195205

196-
const nodeType = checker.getTypeAtLocation(esTreeNodeToTSNodeMap.get(node));
206+
const nodeType = checker.getTypeAtLocation(node);
197207
const constrained = checker.getBaseConstraintOfType(nodeType);
198208
return constrained ?? nodeType;
199209
}

tests/rules/prefer-tacit/ts/invalid.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,29 @@ const tests: Array<
237237
},
238238
],
239239
},
240+
// Boolean constructor
241+
{
242+
code: dedent`
243+
const foo = [1, 2, 3].map(x => Boolean(x));
244+
`,
245+
optionsSet: [[]],
246+
errors: [
247+
{
248+
messageId: "generic",
249+
type: AST_NODE_TYPES.ArrowFunctionExpression,
250+
line: 1,
251+
column: 27,
252+
suggestions: [
253+
{
254+
messageId: "generic",
255+
output: dedent`
256+
const foo = [1, 2, 3].map(Boolean);
257+
`,
258+
},
259+
],
260+
},
261+
],
262+
},
240263
// Instantiation Expression not supported.
241264
{
242265
code: dedent`

0 commit comments

Comments
 (0)