diff --git a/src/converters/lintConfigs/rules/ruleConverters.ts b/src/converters/lintConfigs/rules/ruleConverters.ts index e83453f26..51c9a34c9 100644 --- a/src/converters/lintConfigs/rules/ruleConverters.ts +++ b/src/converters/lintConfigs/rules/ruleConverters.ts @@ -321,6 +321,7 @@ import { convertTemplateUseTrackByFunction } from "./ruleConverters/template-use import { convertTrailingComma } from "./ruleConverters/trailing-comma"; import { convertTripleEquals } from "./ruleConverters/triple-equals"; import { convertTypeLiteralDelimiter } from "./ruleConverters/type-literal-delimiter"; +import { convertTypedef } from "./ruleConverters/typedef"; import { convertTypedefWhitespace } from "./ruleConverters/typedef-whitespace"; import { convertTypeofCompare } from "./ruleConverters/typeof-compare"; import { convertUnderscoreConsistentInvocation } from "./ruleConverters/underscore-consistent-invocation"; @@ -669,6 +670,7 @@ export const ruleConverters = new Map([ ["trailing-comma", convertTrailingComma], ["triple-equals", convertTripleEquals], ["type-literal-delimiter", convertTypeLiteralDelimiter], + ["typedef", convertTypedef], ["typedef-whitespace", convertTypedefWhitespace], ["typeof-compare", convertTypeofCompare], ["underscore-consistent-invocation", convertUnderscoreConsistentInvocation], diff --git a/src/converters/lintConfigs/rules/ruleConverters/tests/typedef.test.ts b/src/converters/lintConfigs/rules/ruleConverters/tests/typedef.test.ts new file mode 100644 index 000000000..e13d9b9c1 --- /dev/null +++ b/src/converters/lintConfigs/rules/ruleConverters/tests/typedef.test.ts @@ -0,0 +1,177 @@ +import { describe, expect, test } from "@jest/globals"; + +import { convertTypedef } from "../typedef"; + +describe("convertTypedef", () => { + test("conversion without arguments", () => { + const result = convertTypedef({ + ruleArguments: [], + }); + + expect(result).toEqual({ + rules: [ + { + ruleName: "@typescript-eslint/typedef", + }, + { + ruleName: "@typescript-eslint/explicit-function-return-type", + }, + { + ruleName: "@typescript-eslint/explicit-module-boundary-types", + }, + ], + }); + }); + + test("conversion with a few arguments", () => { + const result = convertTypedef({ + ruleArguments: [ + "parameter", + "variable-declaration-ignore-function", + "array-destructuring", + ], + }); + + expect(result).toEqual({ + rules: [ + { + ruleArguments: [ + { + parameter: true, + variableDeclarationIgnoreFunction: true, + arrayDestructuring: true, + }, + ], + ruleName: "@typescript-eslint/typedef", + }, + { + ruleName: "@typescript-eslint/explicit-function-return-type", + }, + { + ruleName: "@typescript-eslint/explicit-module-boundary-types", + }, + ], + }); + }); + + test("conversion with all arguments", () => { + const result = convertTypedef({ + ruleArguments: [ + "parameter", + "arrow-parameter", + "property-declaration", + "variable-declaration", + "variable-declaration-ignore-function", + "member-variable-declaration", + "object-destructuring", + "array-destructuring", + ], + }); + + expect(result).toEqual({ + rules: [ + { + ruleArguments: [ + { + parameter: true, + arrowParameter: true, + propertyDeclaration: true, + variableDeclaration: true, + variableDeclarationIgnoreFunction: true, + memberVariableDeclaration: true, + objectDestructuring: true, + arrayDestructuring: true, + }, + ], + ruleName: "@typescript-eslint/typedef", + }, + { + ruleName: "@typescript-eslint/explicit-function-return-type", + }, + { + ruleName: "@typescript-eslint/explicit-module-boundary-types", + }, + ], + }); + }); + + test("conversion with call-signature", () => { + const result = convertTypedef({ + ruleArguments: ["call-signature"], + }); + + expect(result).toEqual({ + notices: [ + "ESLint does not differentiate between the call signatures of arrow and non-arrow functions. Both will be checked", + ], + rules: [ + { + ruleName: "@typescript-eslint/typedef", + }, + { + ruleArguments: [ + { + allowExpressions: false, + allowTypedFunctionExpressions: false, + allowHigherOrderFunctions: false, + allowDirectConstAssertionInArrowFunctions: true, + allowConciseArrowFunctionExpressionsStartingWithVoid: true, + }, + ], + ruleName: "@typescript-eslint/explicit-function-return-type", + }, + { + ruleArguments: [ + { + allowArgumentsExplicitlyTypedAsAny: true, + allowDirectConstAssertionInArrowFunctions: true, + allowHigherOrderFunctions: false, + allowTypedFunctionExpressions: false, + }, + ], + ruleName: "@typescript-eslint/explicit-module-boundary-types", + }, + ], + }); + }); + + test("conversion with arrow-call-signature", () => { + const result = convertTypedef({ + ruleArguments: ["arrow-call-signature"], + }); + + expect(result).toEqual({ + notices: [ + "ESLint does not differentiate between the call signatures of arrow and non-arrow functions. Both will be checked", + ], + rules: [ + { + ruleName: "@typescript-eslint/typedef", + }, + { + ruleArguments: [ + { + allowExpressions: false, + allowTypedFunctionExpressions: false, + allowHigherOrderFunctions: false, + allowDirectConstAssertionInArrowFunctions: true, + allowConciseArrowFunctionExpressionsStartingWithVoid: true, + }, + ], + ruleName: "@typescript-eslint/explicit-function-return-type", + }, + { + ruleArguments: [ + { + allowArgumentsExplicitlyTypedAsAny: true, + allowDirectConstAssertionInArrowFunctions: true, + allowHigherOrderFunctions: false, + allowTypedFunctionExpressions: false, + }, + ], + ruleName: "@typescript-eslint/explicit-module-boundary-types", + }, + ], + }); + }); +}); diff --git a/src/converters/lintConfigs/rules/ruleConverters/typedef.ts b/src/converters/lintConfigs/rules/ruleConverters/typedef.ts new file mode 100644 index 000000000..b0a5cb842 --- /dev/null +++ b/src/converters/lintConfigs/rules/ruleConverters/typedef.ts @@ -0,0 +1,67 @@ +import { RuleConverter } from "../ruleConverter"; + +export const convertTypedef: RuleConverter = (tslintRule) => { + const typedefRule: Record = {}; + const functionReturnRule: Record = {}; + const moduleBoundaryRule: Record = {}; + + const originalArguments = new Set(tslintRule.ruleArguments); + + const argumentEquivalents = { + parameter: "parameter", + "arrow-parameter": "arrowParameter", + "property-declaration": "propertyDeclaration", + "variable-declaration": "variableDeclaration", + "variable-declaration-ignore-function": "variableDeclarationIgnoreFunction", + "member-variable-declaration": "memberVariableDeclaration", + "object-destructuring": "objectDestructuring", + "array-destructuring": "arrayDestructuring", + }; + + for (const [tslintArgument, eslintArgument] of Object.entries(argumentEquivalents)) { + if (originalArguments.has(tslintArgument)) typedefRule[eslintArgument] = true; + } + + const checksFunctionCallSignture = + originalArguments.has("arrow-call-signature") || originalArguments.has("call-signature"); + if (checksFunctionCallSignture) { + functionReturnRule.allowExpressions = false; + functionReturnRule.allowTypedFunctionExpressions = false; + functionReturnRule.allowHigherOrderFunctions = false; + functionReturnRule.allowDirectConstAssertionInArrowFunctions = true; + functionReturnRule.allowConciseArrowFunctionExpressionsStartingWithVoid = true; + + moduleBoundaryRule.allowArgumentsExplicitlyTypedAsAny = true; + moduleBoundaryRule.allowDirectConstAssertionInArrowFunctions = true; + moduleBoundaryRule.allowHigherOrderFunctions = false; + moduleBoundaryRule.allowTypedFunctionExpressions = false; + } + + return { + ...(checksFunctionCallSignture && { + notices: [ + "ESLint does not differentiate between the call signatures of arrow and non-arrow functions. Both will be checked", + ], + }), + rules: [ + { + ...(Object.keys(typedefRule).length !== 0 && { + ruleArguments: [typedefRule], + }), + ruleName: "@typescript-eslint/typedef", + }, + { + ...(Object.keys(functionReturnRule).length !== 0 && { + ruleArguments: [functionReturnRule], + }), + ruleName: "@typescript-eslint/explicit-function-return-type", + }, + { + ...(Object.keys(moduleBoundaryRule).length !== 0 && { + ruleArguments: [moduleBoundaryRule], + }), + ruleName: "@typescript-eslint/explicit-module-boundary-types", + }, + ], + }; +};