Skip to content

Commit

Permalink
fix(prefer-tacit): handling functions that don't map to directly to a…
Browse files Browse the repository at this point in the history
…n eslint node (#802)

Fix 801
  • Loading branch information
RebeccaStevens authored Apr 14, 2024
1 parent 4558b4a commit 423e249
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 14 deletions.
16 changes: 6 additions & 10 deletions src/rules/prefer-tacit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,17 @@ import { ruleNameScope } from "#eslint-plugin-functional/utils/misc";
import { type ESFunction } from "#eslint-plugin-functional/utils/node-types";
import {
createRule,
getESTreeNode,
getTypeOfNode,
getTypeOfTSNode,
type NamedCreateRuleCustomMeta,
type RuleResult,
} from "#eslint-plugin-functional/utils/rule";
import { isNested } from "#eslint-plugin-functional/utils/tree";
import {
isBlockStatement,
isCallExpression,
isDefined,
isFunctionLike,
isIdentifier,
isReturnStatement,
isTSFunctionType,
} from "#eslint-plugin-functional/utils/type-guards";

/**
Expand Down Expand Up @@ -106,13 +103,12 @@ function isCallerViolation(
if (tsDeclaration === undefined) {
return false;
}
const declaration = getESTreeNode(tsDeclaration, context);

return (
isDefined(declaration) &&
(isFunctionLike(declaration) || isTSFunctionType(declaration)) &&
declaration.params.length === caller.arguments.length
);
return getTypeOfTSNode(tsDeclaration, context)
.getCallSignatures()
.some(
(signature) => signature.parameters.length === caller.arguments.length,
);
}

/**
Expand Down
18 changes: 14 additions & 4 deletions src/utils/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,22 @@ export function getTypeOfNode<Context extends RuleContext<string, BaseOptions>>(
node: TSESTree.Node,
context: Context,
): Type {
const parserServices = getParserServices(context);
const { esTreeNodeToTSNodeMap } = getParserServices(context);

const checker = parserServices.program.getTypeChecker();
const { esTreeNodeToTSNodeMap } = parserServices;
const tsNode = esTreeNodeToTSNodeMap.get(node);
return getTypeOfTSNode(tsNode, context);
}

/**
* Get the type of the the given ts node.
*/
export function getTypeOfTSNode<
Context extends RuleContext<string, BaseOptions>,
>(node: TSNode, context: Context): Type {
const { program } = getParserServices(context);
const checker = program.getTypeChecker();

const nodeType = checker.getTypeAtLocation(esTreeNodeToTSNodeMap.get(node));
const nodeType = checker.getTypeAtLocation(node);
const constrained = checker.getBaseConstraintOfType(nodeType);
return constrained ?? nodeType;
}
Expand Down
23 changes: 23 additions & 0 deletions tests/rules/prefer-tacit/ts/invalid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,29 @@ const tests: Array<
},
],
},
// Boolean constructor
{
code: dedent`
const foo = [1, 2, 3].map(x => Boolean(x));
`,
optionsSet: [[]],
errors: [
{
messageId: "generic",
type: AST_NODE_TYPES.ArrowFunctionExpression,
line: 1,
column: 27,
suggestions: [
{
messageId: "generic",
output: dedent`
const foo = [1, 2, 3].map(Boolean);
`,
},
],
},
],
},
// Instantiation Expression not supported.
{
code: dedent`
Expand Down

0 comments on commit 423e249

Please sign in to comment.