eslint-plugin-signature-design
Version:
ESLint rule to make function signatures better. Currently has only one rule: prevent functions from having too many arguments with the same type.
88 lines (87 loc) • 3.49 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const createRule = utils_1.ESLintUtils.RuleCreator((name) => `https://github.com/Vladyslav-Soldatenko/eslint-plugin-signature-designn/blob/main/docs/rules/${name}.md`);
exports.default = createRule({
name: 'max-duplicate-param-types',
meta: {
type: 'suggestion',
docs: {
description: 'Disallow using too many parameters of the same type in a function signature',
},
messages: {
tooManyOfSameType: 'Too many parameters of the same type "{{type}}" ({{count}} > {{max}}). It is easy to confuse the order of arguments when they have the same type. Refactor the function signature to accept object.',
},
schema: [
{
type: 'object',
properties: {
maxOfSameType: {
type: 'integer',
minimum: 1,
},
},
additionalProperties: false,
},
],
},
defaultOptions: [{ maxOfSameType: 2 }],
create(context, [options]) {
const maxAllowed = options.maxOfSameType ?? 2;
const sourceCode = context.sourceCode;
function getTypeNode(param) {
switch (param.type) {
case utils_1.AST_NODE_TYPES.Identifier:
return param.typeAnnotation
? param.typeAnnotation.typeAnnotation
: null;
case utils_1.AST_NODE_TYPES.AssignmentPattern: {
const left = param.left;
if (left.type === utils_1.AST_NODE_TYPES.Identifier && left.typeAnnotation) {
return left.typeAnnotation.typeAnnotation;
}
return null;
}
case utils_1.AST_NODE_TYPES.RestElement: {
const arg = param.argument;
if (arg.type === utils_1.AST_NODE_TYPES.Identifier && arg.typeAnnotation) {
return arg.typeAnnotation.typeAnnotation;
}
return null;
}
default:
return null;
}
}
function checkFunctionParams(node) {
const counts = Object.create(null);
for (const param of node.params) {
const tsType = getTypeNode(param);
if (!tsType) {
continue;
}
const typeText = sourceCode.getText(tsType);
const prev = counts[typeText] ?? 0;
const next = prev + 1;
counts[typeText] = next;
if (next > maxAllowed) {
context.report({
node: tsType,
messageId: 'tooManyOfSameType',
data: {
type: typeText,
count: next,
max: maxAllowed,
},
});
counts[typeText] = -Infinity;
}
}
}
return {
FunctionDeclaration: checkFunctionParams,
FunctionExpression: checkFunctionParams,
ArrowFunctionExpression: checkFunctionParams,
};
},
});