@checkdigit/eslint-plugin 6.6.0-PR.75-7c7f → 6.6.0-PR.75-487e

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12324,7 +12324,7 @@
12324
12324
  "format": "esm"
12325
12325
  },
12326
12326
  "src/agent/fix-function-call-arguments.ts": {
12327
- "bytes": 5924,
12327
+ "bytes": 6880,
12328
12328
  "imports": [
12329
12329
  {
12330
12330
  "path": "node_modules/@typescript-eslint/utils/dist/index.js",
@@ -15743,10 +15743,10 @@
15743
15743
  "bytesInOutput": 12231
15744
15744
  },
15745
15745
  "src/agent/fix-function-call-arguments.ts": {
15746
- "bytesInOutput": 5235
15746
+ "bytesInOutput": 6098
15747
15747
  },
15748
15748
  "src/invalid-json-stringify.ts": {
15749
- "bytesInOutput": 2473
15749
+ "bytesInOutput": 2475
15750
15750
  },
15751
15751
  "src/no-duplicated-imports.ts": {
15752
15752
  "bytesInOutput": 3736
@@ -15821,7 +15821,7 @@
15821
15821
  "bytesInOutput": 3362
15822
15822
  }
15823
15823
  },
15824
- "bytes": 4371841
15824
+ "bytes": 4373358
15825
15825
  }
15826
15826
  }
15827
15827
  }
@@ -4,6 +4,9 @@ import { strict as assert } from "node:assert";
4
4
  import debug from "debug";
5
5
  import getDocumentationUrl from "../get-documentation-url.mjs";
6
6
  var ruleId = "fix-function-call-arguments";
7
+ var DEFAULT_OPTIONS = {
8
+ typesToCheck: ["Configuration<ResolvedServices>", "EMPTY_CONTEXT", "Fixture"]
9
+ };
7
10
  var createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
8
11
  var log = debug("eslint-plugin:fix-function-call-arguments");
9
12
  var rule = createRule({
@@ -18,10 +21,25 @@ var rule = createRule({
18
21
  unknownError: 'Unknown error occurred in file "{{fileName}}": {{ error }}.'
19
22
  },
20
23
  fixable: "code",
21
- schema: []
24
+ schema: [
25
+ {
26
+ type: "object",
27
+ properties: {
28
+ typesToCheck: {
29
+ description: "Text representation of the types of which the function call parameters will be examine",
30
+ type: "array",
31
+ items: {
32
+ type: "string"
33
+ }
34
+ }
35
+ },
36
+ additionalProperties: false
37
+ }
38
+ ]
22
39
  },
23
- defaultOptions: [],
40
+ defaultOptions: [DEFAULT_OPTIONS],
24
41
  create(context) {
42
+ const { typesToCheck } = context.options[0];
25
43
  const parserServices = ESLintUtils.getParserServices(context);
26
44
  const typeChecker = parserServices.program.getTypeChecker();
27
45
  const sourceCode = context.sourceCode;
@@ -36,57 +54,59 @@ var rule = createRule({
36
54
  const calleeTsNode = parserServices.esTreeNodeToTSNodeMap.get(callExpression.callee);
37
55
  const calleeType = typeChecker.getTypeAtLocation(calleeTsNode);
38
56
  const signatures = calleeType.getCallSignatures();
39
- if (
40
- // ignore complex signatures with overloads
41
- signatures.length > 1
42
- ) {
57
+ if (signatures.length > 1) {
43
58
  return;
44
59
  }
45
60
  const signature = signatures[0];
46
- if (!signature || // ignore complex signatures
47
- signature.typeParameters !== void 0 && signature.typeParameters.length > 0) {
61
+ assert.ok(signature, "Signature not found.");
62
+ if (signature.typeParameters !== void 0 && signature.typeParameters.length > 0) {
48
63
  return;
49
64
  }
50
- const signatureParameters = signature.getParameters();
51
- const expectedParametersCount = signatureParameters.length;
65
+ log("signature:", signature.getDeclaration().getText());
66
+ const expectedParameters = signature.getParameters();
67
+ log(
68
+ "expected parameters:",
69
+ expectedParameters.map(
70
+ (expectedParameter) => typeChecker.typeToString(typeChecker.getTypeOfSymbol(expectedParameter))
71
+ )
72
+ );
73
+ const expectedParametersCount = expectedParameters.length;
52
74
  const actualParameters = callExpression.arguments;
53
75
  const actualParametersCount = actualParameters.length;
54
76
  if (actualParametersCount === 0 || actualParametersCount === expectedParametersCount) {
55
77
  return;
56
78
  }
57
79
  const parametersToKeep = [];
58
- if (expectedParametersCount > 0) {
59
- let expectedParameterIndex = 0;
60
- for (const [actualParameterIndex, actualParameter] of actualParameters.entries()) {
61
- if (expectedParameterIndex >= expectedParametersCount) {
62
- parametersToKeep.push(actualParameter);
63
- continue;
64
- }
65
- const expectedParameter = signatureParameters[expectedParameterIndex];
66
- assert.ok(expectedParameter, "Expected parameter not found.");
67
- const expectedType = typeChecker.getTypeOfSymbol(expectedParameter);
68
- const actualType = typeChecker.getTypeAtLocation(
69
- parserServices.esTreeNodeToTSNodeMap.get(actualParameter)
70
- );
71
- log(
72
- "expected type: #",
73
- expectedParameterIndex,
74
- expectedParameter.escapedName,
75
- typeChecker.typeToString(expectedType)
76
- );
77
- log(
78
- "actual type: #",
79
- actualParameterIndex,
80
- sourceCode.getText(actualParameter),
81
- typeChecker.typeToString(actualType)
82
- );
83
- if (typeChecker.isTypeAssignableTo(actualType, expectedType) === true) {
84
- parametersToKeep.push(actualParameter);
85
- expectedParameterIndex++;
86
- log("matched");
87
- } else {
88
- log("not matched");
89
- }
80
+ let expectedParameterIndex = 0;
81
+ for (const [actualParameterIndex, actualParameter] of actualParameters.entries()) {
82
+ if (expectedParameterIndex >= expectedParametersCount) {
83
+ break;
84
+ }
85
+ const expectedParameter = expectedParameters[expectedParameterIndex];
86
+ assert.ok(expectedParameter, "Expected parameter not found.");
87
+ const expectedType = typeChecker.getTypeOfSymbol(expectedParameter);
88
+ const actualType = typeChecker.getTypeAtLocation(parserServices.esTreeNodeToTSNodeMap.get(actualParameter));
89
+ const actualTypeString = typeChecker.typeToString(actualType);
90
+ log(
91
+ "expected type: #",
92
+ expectedParameterIndex,
93
+ expectedParameter.escapedName,
94
+ typeChecker.typeToString(expectedType)
95
+ );
96
+ log("actual type: #", actualParameterIndex, sourceCode.getText(actualParameter), actualTypeString);
97
+ if (!typesToCheck.includes(actualTypeString)) {
98
+ parametersToKeep.push(actualParameter);
99
+ log("skipped");
100
+ } else if (
101
+ // @ts-expect-error: this is typescript's internal API
102
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
103
+ typeChecker.isTypeAssignableTo(actualType, expectedType) === true
104
+ ) {
105
+ parametersToKeep.push(actualParameter);
106
+ log("matched");
107
+ expectedParameterIndex++;
108
+ } else {
109
+ log("not matched");
90
110
  }
91
111
  }
92
112
  if (parametersToKeep.length === actualParametersCount) {
@@ -129,4 +149,4 @@ export {
129
149
  fix_function_call_arguments_default as default,
130
150
  ruleId
131
151
  };
132
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FnZW50L2ZpeC1mdW5jdGlvbi1jYWxsLWFyZ3VtZW50cy50cyJdLAogICJtYXBwaW5ncyI6ICI7QUFRQSxTQUFTLGFBQWEsZ0JBQWdCO0FBQ3RDLFNBQVMsVUFBVSxjQUFjO0FBQ2pDLE9BQU8sV0FBVztBQUNsQixPQUFPLHlCQUF5QjtBQUV6QixJQUFNLFNBQVM7QUFFdEIsSUFBTSxhQUFhLFlBQVksWUFBWSxDQUFDLFNBQVMsb0JBQW9CLElBQUksQ0FBQztBQUM5RSxJQUFNLE1BQU0sTUFBTSwyQ0FBMkM7QUFFN0QsSUFBTSxPQUFPLFdBQVc7QUFBQSxFQUN0QixNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsSUFDSixNQUFNO0FBQUEsSUFDTixNQUFNO0FBQUEsTUFDSixhQUFhO0FBQUEsSUFDZjtBQUFBLElBQ0EsVUFBVTtBQUFBLE1BQ1IscUNBQXFDO0FBQUEsTUFDckMsY0FBYztBQUFBLElBQ2hCO0FBQUEsSUFDQSxTQUFTO0FBQUEsSUFDVCxRQUFRLENBQUM7QUFBQSxFQUNYO0FBQUEsRUFDQSxnQkFBZ0IsQ0FBQztBQUFBLEVBQ2pCLE9BQU8sU0FBUztBQUNkLFVBQU0saUJBQWlCLFlBQVksa0JBQWtCLE9BQU87QUFDNUQsVUFBTSxjQUFjLGVBQWUsUUFBUSxlQUFlO0FBQzFELFVBQU0sYUFBYSxRQUFRO0FBRTNCLFdBQU87QUFBQSxNQUNMLGVBQWUsZ0JBQWdCO0FBRzdCLFlBQUksZUFBZSxPQUFPLFNBQVMsU0FBUyxlQUFlLGtCQUFrQjtBQUMzRTtBQUFBLFFBQ0Y7QUFFQSxZQUFJLG9CQUFvQixRQUFRLFFBQVE7QUFDeEMsWUFBSSxtQkFBbUIsV0FBVyxRQUFRLGNBQWMsQ0FBQztBQUN6RCxZQUFJO0FBQ0YsZ0JBQU0sZUFBZSxlQUFlLHNCQUFzQixJQUFJLGVBQWUsTUFBTTtBQUNuRixnQkFBTSxhQUFhLFlBQVksa0JBQWtCLFlBQVk7QUFFN0QsZ0JBQU0sYUFBYSxXQUFXLGtCQUFrQjtBQUNoRDtBQUFBO0FB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
152
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FnZW50L2ZpeC1mdW5jdGlvbi1jYWxsLWFyZ3VtZW50cy50cyJdLAogICJtYXBwaW5ncyI6ICI7QUFRQSxTQUFTLGFBQWEsZ0JBQWdCO0FBQ3RDLFNBQVMsVUFBVSxjQUFjO0FBQ2pDLE9BQU8sV0FBVztBQUNsQixPQUFPLHlCQUF5QjtBQUV6QixJQUFNLFNBQVM7QUFLdEIsSUFBTSxrQkFBa0I7QUFBQSxFQUN0QixjQUFjLENBQUMsbUNBQW1DLGlCQUFpQixTQUFTO0FBQzlFO0FBRUEsSUFBTSxhQUFhLFlBQVksWUFBWSxDQUFDLFNBQVMsb0JBQW9CLElBQUksQ0FBQztBQUM5RSxJQUFNLE1BQU0sTUFBTSwyQ0FBMkM7QUFFN0QsSUFBTSxPQUFPLFdBQVc7QUFBQSxFQUN0QixNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsSUFDSixNQUFNO0FBQUEsSUFDTixNQUFNO0FBQUEsTUFDSixhQUFhO0FBQUEsSUFDZjtBQUFBLElBQ0EsVUFBVTtBQUFBLE1BQ1IscUNBQXFDO0FBQUEsTUFDckMsY0FBYztBQUFBLElBQ2hCO0FBQUEsSUFDQSxTQUFTO0FBQUEsSUFDVCxRQUFRO0FBQUEsTUFDTjtBQUFBLFFBQ0UsTUFBTTtBQUFBLFFBQ04sWUFBWTtBQUFBLFVBQ1YsY0FBYztBQUFBLFlBQ1osYUFBYTtBQUFBLFlBQ2IsTUFBTTtBQUFBLFlBQ04sT0FBTztBQUFBLGNBQ0wsTUFBTTtBQUFBLFlBQ1I7QUFBQSxVQUNGO0FBQUEsUUFDRjtBQUFBLFFBQ0Esc0JBQXNCO0FBQUEsTUFDeEI7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUFBLEVBQ0EsZ0JBQWdCLENBQUMsZUFBZTtBQUFBLEVBQ2hDLE9BQU8sU0FBUztBQUNkLFVBQU0sRUFBRSxhQUFhLElBQUksUUFBUSxRQUFRLENBQUM7QUFDMUMsVUFBTSxpQkFBaUIsWUFBWSxrQkFBa0IsT0FBTztBQUM1RCxVQUFNLGNBQWMsZUFBZSxRQUFRLGVBQWU7QUFDMUQsVUFBTSxhQUFhLFFBQVE7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
@@ -1,4 +1,9 @@
1
1
  import { ESLintUtils } from '@typescript-eslint/utils';
2
2
  export declare const ruleId = "fix-function-call-arguments";
3
- declare const rule: ESLintUtils.RuleModule<"unknownError" | "removeIncompatibleFunctionArguments", never[], ESLintUtils.RuleListener>;
3
+ export interface FixFunctionCallArgumentsRuleOptions {
4
+ typesToCheck: string[];
5
+ }
6
+ declare const rule: ESLintUtils.RuleModule<"unknownError" | "removeIncompatibleFunctionArguments", {
7
+ typesToCheck: string[];
8
+ }[], ESLintUtils.RuleListener>;
4
9
  export default rule;
@@ -27,7 +27,9 @@ declare const _default: {
27
27
  "no-unused-function-argument": import("@typescript-eslint/utils/ts-eslint").RuleModule<"unknownError" | "removeUnusedFunctionArguments", never[], import("@typescript-eslint/utils/ts-eslint").RuleListener>;
28
28
  "no-unused-service-variable": import("@typescript-eslint/utils/ts-eslint").RuleModule<"unknownError" | "removeUnusedServiceVariables", never[], import("@typescript-eslint/utils/ts-eslint").RuleListener>;
29
29
  "no-unused-imports": import("@typescript-eslint/utils/ts-eslint").RuleModule<"unknownError" | "removeUnusedImports", never[], import("@typescript-eslint/utils/ts-eslint").RuleListener>;
30
- "fix-function-call-arguments": import("@typescript-eslint/utils/ts-eslint").RuleModule<"unknownError" | "removeIncompatibleFunctionArguments", never[], import("@typescript-eslint/utils/ts-eslint").RuleListener>;
30
+ "fix-function-call-arguments": import("@typescript-eslint/utils/ts-eslint").RuleModule<"unknownError" | "removeIncompatibleFunctionArguments", {
31
+ typesToCheck: string[];
32
+ }[], import("@typescript-eslint/utils/ts-eslint").RuleListener>;
31
33
  };
32
34
  configs: {
33
35
  all: {
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@checkdigit/eslint-plugin","version":"6.6.0-PR.75-7c7f","description":"Check Digit eslint plugins","keywords":["eslint","eslintplugin"],"homepage":"https://github.com/checkdigit/eslint-plugin#readme","bugs":{"url":"https://github.com/checkdigit/eslint-plugin/issues"},"repository":{"type":"git","url":"https://github.com/checkdigit/eslint-plugin"},"license":"MIT","author":"Check Digit, LLC","sideEffects":false,"type":"module","exports":{".":{"types":"./dist-types/index.d.ts","require":"./dist-cjs/index.cjs","import":"./dist-mjs/index.mjs","default":"./dist-mjs/index.mjs"}},"files":["src","dist-types","dist-cjs","dist-mjs","!src/**/*.test.ts","!src/**/*.spec.ts","!dist-types/**/*.test.d.ts","!dist-types/**/*.spec.d.ts","!dist-cjs/**/*.test.cjs","!dist-cjs/**/*.spec.cjs","!dist-mjs/**/*.test.mjs","!dist-mjs/**/*.spec.mjs","SECURITY.md"],"scripts":{"build:dist-cjs":"rimraf dist-cjs && npx builder --type=commonjs --sourceMap --entryPoint=index.ts --outDir=dist-cjs --outFile=index.cjs --external=espree && echo \"module.exports = module.exports.default;\" >> dist-cjs/index.cjs","build:dist-mjs":"rimraf dist-mjs && npx builder --type=module --sourceMap --outDir=dist-mjs && node dist-mjs/index.mjs","build:dist-types":"rimraf dist-types && npx builder --type=types --outDir=dist-types","ci:compile":"tsc --noEmit","ci:coverage":"NODE_OPTIONS=\"--disable-warning ExperimentalWarning --experimental-vm-modules\" jest --coverage=true","ci:lint":"npm run lint","ci:style":"npm run prettier","ci:test":"NODE_OPTIONS=\"--disable-warning ExperimentalWarning --experimental-vm-modules\" jest --coverage=false","lint":"eslint --max-warnings 0 --ignore-path .gitignore .","lint:fix":"eslint --ignore-path .gitignore . --fix","prepublishOnly":"npm run build:dist-types && npm run build:dist-cjs && npm run build:dist-mjs","prettier":"prettier --ignore-path .gitignore --list-different .","prettier:fix":"prettier --ignore-path .gitignore --write .","test":"npm run ci:compile && npm run ci:test && npm run ci:lint && npm run ci:style"},"prettier":"@checkdigit/prettier-config","jest":{"preset":"@checkdigit/jest-config"},"dependencies":{"@typescript-eslint/type-utils":"7.18.0","@typescript-eslint/utils":"7.18.0","debug":"^4.3.7","ts-api-utils":"^1.3.0"},"devDependencies":{"@checkdigit/jest-config":"^6.0.2","@checkdigit/prettier-config":"^5.5.0","@checkdigit/typescript-config":"6.0.0","@types/debug":"^4.1.12","@types/eslint":"8.56.10","@typescript-eslint/eslint-plugin":"7.18.0","@typescript-eslint/parser":"7.18.0","@typescript-eslint/rule-tester":"7.18.0","eslint-config-prettier":"^9.1.0","eslint-plugin-eslint-plugin":"^6.2.0","eslint-plugin-import":"^2.29.1","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-no-secrets":"^1.0.2","eslint-plugin-node":"^11.1.0","eslint-plugin-sonarjs":"0.24.0","http-status-codes":"^2.3.0"},"peerDependencies":{"eslint":">=8 <9"},"engines":{"node":">=20.14"}}
1
+ {"name":"@checkdigit/eslint-plugin","version":"6.6.0-PR.75-487e","description":"Check Digit eslint plugins","keywords":["eslint","eslintplugin"],"homepage":"https://github.com/checkdigit/eslint-plugin#readme","bugs":{"url":"https://github.com/checkdigit/eslint-plugin/issues"},"repository":{"type":"git","url":"https://github.com/checkdigit/eslint-plugin"},"license":"MIT","author":"Check Digit, LLC","sideEffects":false,"type":"module","exports":{".":{"types":"./dist-types/index.d.ts","require":"./dist-cjs/index.cjs","import":"./dist-mjs/index.mjs","default":"./dist-mjs/index.mjs"}},"files":["src","dist-types","dist-cjs","dist-mjs","!src/**/*.test.ts","!src/**/*.spec.ts","!dist-types/**/*.test.d.ts","!dist-types/**/*.spec.d.ts","!dist-cjs/**/*.test.cjs","!dist-cjs/**/*.spec.cjs","!dist-mjs/**/*.test.mjs","!dist-mjs/**/*.spec.mjs","SECURITY.md"],"scripts":{"build:dist-cjs":"rimraf dist-cjs && npx builder --type=commonjs --sourceMap --entryPoint=index.ts --outDir=dist-cjs --outFile=index.cjs --external=espree && echo \"module.exports = module.exports.default;\" >> dist-cjs/index.cjs","build:dist-mjs":"rimraf dist-mjs && npx builder --type=module --sourceMap --outDir=dist-mjs && node dist-mjs/index.mjs","build:dist-types":"rimraf dist-types && npx builder --type=types --outDir=dist-types","ci:compile":"tsc --noEmit","ci:coverage":"NODE_OPTIONS=\"--disable-warning ExperimentalWarning --experimental-vm-modules\" jest --coverage=true","ci:lint":"npm run lint","ci:style":"npm run prettier","ci:test":"NODE_OPTIONS=\"--disable-warning ExperimentalWarning --experimental-vm-modules\" jest --coverage=false","lint":"eslint --max-warnings 0 --ignore-path .gitignore .","lint:fix":"eslint --ignore-path .gitignore . --fix","prepublishOnly":"npm run build:dist-types && npm run build:dist-cjs && npm run build:dist-mjs","prettier":"prettier --ignore-path .gitignore --list-different .","prettier:fix":"prettier --ignore-path .gitignore --write .","test":"npm run ci:compile && npm run ci:test && npm run ci:lint && npm run ci:style"},"prettier":"@checkdigit/prettier-config","jest":{"preset":"@checkdigit/jest-config"},"dependencies":{"@typescript-eslint/type-utils":"7.18.0","@typescript-eslint/utils":"7.18.0","debug":"^4.3.7","ts-api-utils":"^1.3.0"},"devDependencies":{"@checkdigit/jest-config":"^6.0.2","@checkdigit/prettier-config":"^5.5.0","@checkdigit/typescript-config":"6.0.0","@types/debug":"^4.1.12","@types/eslint":"8.56.10","@typescript-eslint/eslint-plugin":"7.18.0","@typescript-eslint/parser":"7.18.0","@typescript-eslint/rule-tester":"7.18.0","eslint-config-prettier":"^9.1.0","eslint-plugin-eslint-plugin":"^6.2.0","eslint-plugin-import":"^2.29.1","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-no-secrets":"^1.0.2","eslint-plugin-node":"^11.1.0","eslint-plugin-sonarjs":"0.24.0","http-status-codes":"^2.3.0"},"peerDependencies":{"eslint":">=8 <9"},"engines":{"node":">=20.14"}}
@@ -13,6 +13,13 @@ import getDocumentationUrl from '../get-documentation-url';
13
13
 
14
14
  export const ruleId = 'fix-function-call-arguments';
15
15
 
16
+ export interface FixFunctionCallArgumentsRuleOptions {
17
+ typesToCheck: string[];
18
+ }
19
+ const DEFAULT_OPTIONS = {
20
+ typesToCheck: ['Configuration<ResolvedServices>', 'EMPTY_CONTEXT', 'Fixture'],
21
+ };
22
+
16
23
  const createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
17
24
  const log = debug('eslint-plugin:fix-function-call-arguments');
18
25
 
@@ -28,10 +35,25 @@ const rule = createRule({
28
35
  unknownError: 'Unknown error occurred in file "{{fileName}}": {{ error }}.',
29
36
  },
30
37
  fixable: 'code',
31
- schema: [],
38
+ schema: [
39
+ {
40
+ type: 'object',
41
+ properties: {
42
+ typesToCheck: {
43
+ description: 'Text representation of the types of which the function call parameters will be examine',
44
+ type: 'array',
45
+ items: {
46
+ type: 'string',
47
+ },
48
+ },
49
+ },
50
+ additionalProperties: false,
51
+ },
52
+ ],
32
53
  },
33
- defaultOptions: [],
54
+ defaultOptions: [DEFAULT_OPTIONS],
34
55
  create(context) {
56
+ const { typesToCheck } = context.options[0] as FixFunctionCallArgumentsRuleOptions;
35
57
  const parserServices = ESLintUtils.getParserServices(context);
36
58
  const typeChecker = parserServices.program.getTypeChecker();
37
59
  const sourceCode = context.sourceCode;
@@ -51,70 +73,69 @@ const rule = createRule({
51
73
  const calleeType = typeChecker.getTypeAtLocation(calleeTsNode);
52
74
 
53
75
  const signatures = calleeType.getCallSignatures();
54
- if (
76
+ if (signatures.length > 1) {
55
77
  // ignore complex signatures with overloads
56
- signatures.length > 1
57
- ) {
58
78
  return;
59
79
  }
60
80
 
61
81
  const signature = signatures[0];
62
- if (
63
- !signature ||
64
- // ignore complex signatures
65
- (signature.typeParameters !== undefined && signature.typeParameters.length > 0)
66
- ) {
82
+ assert.ok(signature, 'Signature not found.');
83
+ if (signature.typeParameters !== undefined && signature.typeParameters.length > 0) {
84
+ // ignore complex signatures with type parameters
67
85
  return;
68
86
  }
69
87
 
70
- const signatureParameters = signature.getParameters();
71
- const expectedParametersCount = signatureParameters.length;
88
+ log('signature:', signature.getDeclaration().getText());
89
+ const expectedParameters = signature.getParameters();
90
+ log(
91
+ 'expected parameters:',
92
+ expectedParameters.map((expectedParameter) =>
93
+ typeChecker.typeToString(typeChecker.getTypeOfSymbol(expectedParameter)),
94
+ ),
95
+ );
96
+ const expectedParametersCount = expectedParameters.length;
72
97
  const actualParameters = callExpression.arguments;
73
98
  const actualParametersCount = actualParameters.length;
74
99
  if (actualParametersCount === 0 || actualParametersCount === expectedParametersCount) {
75
100
  return;
76
101
  }
77
- const parametersToKeep: TSESTree.CallExpressionArgument[] = [];
78
-
79
- if (expectedParametersCount > 0) {
80
- let expectedParameterIndex = 0;
81
- for (const [actualParameterIndex, actualParameter] of actualParameters.entries()) {
82
- if (expectedParameterIndex >= expectedParametersCount) {
83
- parametersToKeep.push(actualParameter);
84
- continue;
85
- }
86
-
87
- const expectedParameter = signatureParameters[expectedParameterIndex];
88
- assert.ok(expectedParameter, 'Expected parameter not found.');
89
102
 
90
- const expectedType = typeChecker.getTypeOfSymbol(expectedParameter);
91
- const actualType = typeChecker.getTypeAtLocation(
92
- parserServices.esTreeNodeToTSNodeMap.get(actualParameter),
93
- );
103
+ const parametersToKeep: TSESTree.CallExpressionArgument[] = [];
104
+ let expectedParameterIndex = 0;
105
+ for (const [actualParameterIndex, actualParameter] of actualParameters.entries()) {
106
+ // eslint-disable-next-line max-depth
107
+ if (expectedParameterIndex >= expectedParametersCount) {
108
+ break;
109
+ }
94
110
 
95
- // eslint-disable-next-line no-console
96
- log(
97
- 'expected type: #',
98
- expectedParameterIndex,
99
- expectedParameter.escapedName,
100
- typeChecker.typeToString(expectedType),
101
- );
102
- // eslint-disable-next-line no-console
103
- log(
104
- 'actual type: #',
105
- actualParameterIndex,
106
- sourceCode.getText(actualParameter),
107
- typeChecker.typeToString(actualType),
108
- );
109
- // @ts-expect-error: internal API
111
+ const expectedParameter = expectedParameters[expectedParameterIndex];
112
+ assert.ok(expectedParameter, 'Expected parameter not found.');
113
+
114
+ const expectedType = typeChecker.getTypeOfSymbol(expectedParameter);
115
+ const actualType = typeChecker.getTypeAtLocation(parserServices.esTreeNodeToTSNodeMap.get(actualParameter));
116
+ const actualTypeString = typeChecker.typeToString(actualType);
117
+ log(
118
+ 'expected type: #',
119
+ expectedParameterIndex,
120
+ expectedParameter.escapedName,
121
+ typeChecker.typeToString(expectedType),
122
+ );
123
+ log('actual type: #', actualParameterIndex, sourceCode.getText(actualParameter), actualTypeString);
124
+
125
+ if (!typesToCheck.includes(actualTypeString)) {
126
+ // skip the parameter type checking if it's not in the candidate types
127
+ parametersToKeep.push(actualParameter);
128
+ log('skipped');
129
+ } else if (
130
+ // @ts-expect-error: this is typescript's internal API
110
131
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call
111
- if (typeChecker.isTypeAssignableTo(actualType, expectedType) === true) {
112
- parametersToKeep.push(actualParameter);
113
- expectedParameterIndex++;
114
- log('matched');
115
- } else {
116
- log('not matched');
117
- }
132
+ typeChecker.isTypeAssignableTo(actualType, expectedType) === true
133
+ ) {
134
+ parametersToKeep.push(actualParameter);
135
+ log('matched');
136
+ expectedParameterIndex++;
137
+ } else {
138
+ log('not matched');
118
139
  }
119
140
  }
120
141