From 6718c2f43ac6f7e10007b8ff30918021d0c87c1c Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sat, 24 Jun 2023 21:50:11 -0400 Subject: [PATCH 1/6] chore: enabled stylistic-type-checked internally --- .eslintrc.js | 21 +-- packages/ast-spec/tests/fixtures.test.ts | 4 +- .../src/rules/no-poorly-typed-ts-props.ts | 3 +- .../src/rules/plugin-test-formatting.ts | 18 +- .../src/rules/prefer-ast-types-enum.ts | 3 +- packages/eslint-plugin/rules.d.ts | 7 +- packages/eslint-plugin/src/rules/ban-types.ts | 3 +- .../eslint-plugin/src/rules/comma-dangle.ts | 2 +- .../src/rules/consistent-type-exports.ts | 2 +- .../src/rules/consistent-type-imports.ts | 2 +- .../rules/explicit-function-return-type.ts | 12 +- .../rules/explicit-module-boundary-types.ts | 52 ++++-- .../src/rules/func-call-spacing.ts | 3 +- packages/eslint-plugin/src/rules/indent.ts | 28 ++- .../src/rules/lines-around-comment.ts | 2 +- .../src/rules/member-ordering.ts | 3 +- .../rules/naming-convention-utils/format.ts | 8 +- .../src/rules/no-confusing-void-expression.ts | 18 +- .../src/rules/no-dupe-class-members.ts | 2 +- .../rules/no-duplicate-type-constituents.ts | 2 +- .../src/rules/no-extra-parens.ts | 93 +++++---- .../src/rules/no-restricted-imports.ts | 14 +- .../eslint-plugin/src/rules/no-type-alias.ts | 5 +- .../src/rules/no-unnecessary-condition.ts | 26 ++- .../src/rules/no-unsafe-return.ts | 6 +- .../rules/padding-line-between-statements.ts | 9 +- .../src/rules/prefer-regexp-exec.ts | 15 +- .../rules/prefer-string-starts-ends-with.ts | 3 +- .../src/rules/promise-function-async.ts | 3 +- .../src/rules/restrict-plus-operands.ts | 6 +- .../src/rules/sort-type-constituents.ts | 3 +- .../src/rules/switch-exhaustiveness-check.ts | 2 +- packages/eslint-plugin/src/util/astUtils.ts | 2 +- .../src/util/collectUnusedVariables.ts | 2 +- packages/eslint-plugin/tests/configs.test.ts | 4 +- packages/eslint-plugin/tests/docs.test.ts | 6 +- .../eslint-plugin/tools/generate-configs.ts | 4 +- .../src/index.ts | 4 +- packages/rule-tester/src/RuleTester.ts | 7 +- .../src/types/DependencyConstraint.ts | 7 +- .../rule-tester/src/utils/config-validator.ts | 5 +- .../src/utils/validationHelpers.ts | 12 +- packages/rule-tester/tests/RuleTester.test.ts | 10 +- .../src/referencer/ClassVisitor.ts | 24 ++- .../src/referencer/Referencer.ts | 4 +- packages/scope-manager/src/scope/ScopeBase.ts | 8 +- packages/scope-manager/src/scope/WithScope.ts | 4 +- .../es6-destructuring-assignments.test.ts | 130 ++++++------- .../implicit-global-reference.test.ts | 42 ++--- .../tests/eslint-scope/references.test.ts | 18 +- packages/scope-manager/tests/fixtures.test.ts | 4 +- .../type-utils/tests/isTypeReadonly.test.ts | 15 +- packages/types/tools/copy-ast-spec.ts | 12 +- .../create-program/createDefaultProgram.ts | 7 +- .../create-program/createProjectProgram.ts | 2 +- .../getWatchProgramsForProjects.ts | 20 +- .../src/create-program/useProvidedPrograms.ts | 2 +- packages/typescript-estree/src/node-utils.ts | 2 +- .../src/parseSettings/createParseSettings.ts | 2 +- packages/typescript-estree/src/parser.ts | 3 +- .../typescript-estree/src/simple-traverse.ts | 10 +- .../src/ts-estree/ts-nodes.ts | 2 + .../tests/lib/convert.test.ts | 176 +++++++++--------- .../tests/lib/persistentParse.test.ts | 160 ++++++++++++---- .../tests/lib/semanticInfo.test.ts | 4 +- .../ast-utils/eslint-utils/PatternMatcher.ts | 7 +- packages/utils/src/json-schema.ts | 30 +-- packages/utils/src/ts-eslint/CLIEngine.ts | 10 +- packages/utils/src/ts-eslint/Linter.ts | 8 +- packages/utils/src/ts-eslint/Rule.ts | 6 +- packages/utils/src/ts-eslint/SourceCode.ts | 4 +- .../tests/eslint-utils/nullThrows.test.ts | 6 +- packages/visitor-keys/src/visitor-keys.ts | 4 +- .../src/components/OptionsSelector.tsx | 20 +- .../website/src/components/Playground.tsx | 4 +- .../src/components/RulesTable/index.tsx | 29 ++- .../src/components/config/ConfigEditor.tsx | 13 +- .../src/components/editor/LoadedEditor.tsx | 40 +++- .../src/components/inputs/Checkbox.tsx | 6 +- .../website/src/components/inputs/Text.tsx | 4 +- .../src/components/layout/EditorTabs.tsx | 4 +- .../src/components/lib/createEventsBinder.ts | 4 +- .../website/src/components/linter/bridge.ts | 4 +- packages/website/src/hooks/useBool.ts | 7 +- packages/website/src/hooks/useMediaQuery.ts | 3 +- .../src/theme/CodeBlock/Content/String.tsx | 4 +- 86 files changed, 768 insertions(+), 543 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index f6502ce3c885..434309cc8080 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -21,7 +21,8 @@ module.exports = { 'eslint:recommended', 'plugin:eslint-plugin/recommended', 'plugin:@typescript-eslint/recommended-type-checked', - // TODO: consider enabling strict-type-checked and/or stylistic-type-checked + 'plugin:@typescript-eslint/stylistic-type-checked', + // TODO: consider enabling strict-type-checked ], parserOptions: { sourceType: 'module', @@ -52,11 +53,13 @@ module.exports = { // make sure we're not leveraging any deprecated APIs 'deprecation/deprecation': 'error', + // TODO(#7138): Enable this soon ✨ + '@typescript-eslint/prefer-nullish-coalescing': 'off', + // // our plugin :D // - '@typescript-eslint/array-type': 'error', '@typescript-eslint/ban-ts-comment': [ 'error', { @@ -67,7 +70,6 @@ module.exports = { minimumDescriptionLength: 5, }, ], - '@typescript-eslint/consistent-type-definitions': ['error', 'interface'], '@typescript-eslint/consistent-type-imports': [ 'error', { prefer: 'type-imports', disallowTypeAnnotations: true }, @@ -76,18 +78,10 @@ module.exports = { 'error', { allowIIFEs: true }, ], - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/no-empty-function': [ - 'error', - { allow: ['arrowFunctions'] }, - ], '@typescript-eslint/no-explicit-any': 'error', '@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/no-var-requires': 'off', - '@typescript-eslint/prefer-for-of': 'error', - '@typescript-eslint/prefer-optional-chain': 'error', '@typescript-eslint/unbound-method': 'off', - '@typescript-eslint/prefer-as-const': 'error', '@typescript-eslint/restrict-template-expressions': [ 'error', { @@ -98,7 +92,6 @@ module.exports = { allowRegExp: true, }, ], - '@typescript-eslint/sort-type-constituents': 'error', '@typescript-eslint/no-unused-vars': [ 'error', { varsIgnorePattern: '^_', argsIgnorePattern: '^_' }, @@ -238,6 +231,10 @@ module.exports = { 'jest/globals': true, }, rules: { + '@typescript-eslint/no-empty-function': [ + 'error', + { allow: ['arrowFunctions'] }, + ], '@typescript-eslint/no-unsafe-assignment': 'off', '@typescript-eslint/no-unsafe-call': 'off', '@typescript-eslint/no-unsafe-member-access': 'off', diff --git a/packages/ast-spec/tests/fixtures.test.ts b/packages/ast-spec/tests/fixtures.test.ts index 6462d4ab03a6..d04b37b48569 100644 --- a/packages/ast-spec/tests/fixtures.test.ts +++ b/packages/ast-spec/tests/fixtures.test.ts @@ -333,7 +333,9 @@ function nestDescribe(fixture: Fixture, segments = fixture.segments): void { } describe('AST Fixtures', () => { - FIXTURES.forEach(f => nestDescribe(f)); + FIXTURES.forEach(f => { + nestDescribe(f); + }); // once we've run all the tests, snapshot the list of fixtures that have differences for easy reference it('List fixtures with AST differences', () => { diff --git a/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts b/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts index 7b34aa0fd260..ff5d705d1ede 100644 --- a/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts +++ b/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts @@ -78,7 +78,7 @@ export default createRule({ continue; } - return context.report({ + context.report({ node, messageId: banned.fixWith ? 'doNotUseWithFixer' : 'doNotUse', data: banned, @@ -96,6 +96,7 @@ export default createRule({ }, ], }); + return; } }, }; diff --git a/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts b/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts index be81846a116a..0df473be52e5 100644 --- a/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts +++ b/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts @@ -267,7 +267,7 @@ export default createRule({ if (literal.loc.end.line === literal.loc.start.line) { // don't use template strings for single line tests - return context.report({ + context.report({ node: literal, messageId: 'singleLineQuotes', fix(fixer) { @@ -288,6 +288,7 @@ export default createRule({ ]; }, }); + return; } const lines = text.split('\n'); @@ -298,7 +299,7 @@ export default createRule({ const isEndEmpty = lastLine.trimStart() === ''; if (!isStartEmpty || !isEndEmpty) { // multiline template strings must have an empty first/last line - return context.report({ + context.report({ node: literal, messageId: 'templateLiteralEmptyEnds', *fix(fixer) { @@ -317,11 +318,12 @@ export default createRule({ } }, }); + return; } const parentIndent = getExpectedIndentForNode(literal, sourceCode.lines); if (lastLine.length !== parentIndent) { - return context.report({ + context.report({ node: literal, messageId: 'templateLiteralLastLineIndent', fix(fixer) { @@ -331,6 +333,7 @@ export default createRule({ ); }, }); + return; } // remove the empty lines @@ -346,13 +349,14 @@ export default createRule({ const requiresIndent = firstLineIndent.length > 0; if (requiresIndent) { if (firstLineIndent.length !== expectedIndent) { - return context.report({ + context.report({ node: literal, messageId: 'templateStringRequiresIndent', data: { indent: expectedIndent, }, }); + return; } // quick-and-dirty validation that lines are roughly indented correctly @@ -366,13 +370,14 @@ export default createRule({ const indent = matches[1]; if (indent.length < expectedIndent) { - return context.report({ + context.report({ node: literal, messageId: 'templateStringMinimumIndent', data: { indent: expectedIndent, }, }); + return; } } @@ -397,7 +402,7 @@ export default createRule({ .join('\n') : formatted; - return context.report({ + context.report({ node: literal, messageId: isErrorTest ? 'invalidFormattingErrorTest' @@ -412,6 +417,7 @@ export default createRule({ ); }, }); + return; } } diff --git a/packages/eslint-plugin-internal/src/rules/prefer-ast-types-enum.ts b/packages/eslint-plugin-internal/src/rules/prefer-ast-types-enum.ts index e042f328614e..2499503ffa69 100755 --- a/packages/eslint-plugin-internal/src/rules/prefer-ast-types-enum.ts +++ b/packages/eslint-plugin-internal/src/rules/prefer-ast-types-enum.ts @@ -28,7 +28,7 @@ export default createRule({ const report = ( enumName: 'AST_NODE_TYPES' | 'AST_TOKEN_TYPES' | 'DefinitionType', literal: TSESTree.StringLiteral, - ): void => + ): void => { context.report({ data: { enumName, literal: literal.value }, messageId: 'preferEnum', @@ -36,6 +36,7 @@ export default createRule({ fix: fixer => fixer.replaceText(literal, `${enumName}.${literal.value}`), }); + }; return { Literal(node: TSESTree.Literal): void { diff --git a/packages/eslint-plugin/rules.d.ts b/packages/eslint-plugin/rules.d.ts index 9a5272d205c3..fbbcb924410f 100644 --- a/packages/eslint-plugin/rules.d.ts +++ b/packages/eslint-plugin/rules.d.ts @@ -37,8 +37,9 @@ This is likely not portable. A type annotation is necessary. ts(2742) import type { RuleModule } from '@typescript-eslint/utils/ts-eslint'; -export interface TypeScriptESLintRules { - [ruleName: string]: RuleModule; -} +export type TypeScriptESLintRules = Record< + string, + RuleModule +>; declare const rules: TypeScriptESLintRules; export = rules; diff --git a/packages/eslint-plugin/src/rules/ban-types.ts b/packages/eslint-plugin/src/rules/ban-types.ts index 1557e3f998f9..ac22a4c41305 100644 --- a/packages/eslint-plugin/src/rules/ban-types.ts +++ b/packages/eslint-plugin/src/rules/ban-types.ts @@ -260,8 +260,9 @@ export default util.createRule({ TYPE_KEYWORDS, (acc: TSESLint.RuleListener, keyword) => { if (bannedTypes.has(keyword)) { - acc[TYPE_KEYWORDS[keyword]] = (node: TSESTree.Node): void => + acc[TYPE_KEYWORDS[keyword]] = (node: TSESTree.Node): void => { checkBannedTypes(node, keyword); + }; } return acc; diff --git a/packages/eslint-plugin/src/rules/comma-dangle.ts b/packages/eslint-plugin/src/rules/comma-dangle.ts index 029e9e3e6517..a87e48ec082a 100644 --- a/packages/eslint-plugin/src/rules/comma-dangle.ts +++ b/packages/eslint-plugin/src/rules/comma-dangle.ts @@ -98,7 +98,7 @@ export default util.createRule({ 'always-multiline': forceCommaIfMultiline, 'only-multiline': allowCommaIfMultiline, never: forbidComma, - ignore: (): void => {}, + ignore: undefined, }; function last(nodes: TSESTree.Node[]): TSESTree.Node | null { diff --git a/packages/eslint-plugin/src/rules/consistent-type-exports.ts b/packages/eslint-plugin/src/rules/consistent-type-exports.ts index e65451ded1da..3c496ee63d61 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-exports.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-exports.ts @@ -67,7 +67,7 @@ export default util.createRule({ create(context, [{ fixMixedExportsWithInlineTypeSpecifier }]) { const sourceCode = context.getSourceCode(); - const sourceExportsMap: { [key: string]: SourceExports } = {}; + const sourceExportsMap: Record = {}; const services = util.getParserServices(context); /** diff --git a/packages/eslint-plugin/src/rules/consistent-type-imports.ts b/packages/eslint-plugin/src/rules/consistent-type-imports.ts index dfa5e48ed652..2dbf8f1893be 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-imports.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-imports.ts @@ -96,7 +96,7 @@ export default util.createRule({ const fixStyle = option.fixStyle ?? 'separate-type-imports'; const sourceCode = context.getSourceCode(); - const sourceImportsMap: { [key: string]: SourceImports } = {}; + const sourceImportsMap: Record = {}; return { ...(prefer === 'type-imports' diff --git a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts index e57465be8365..718173a0366e 100644 --- a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts @@ -196,13 +196,13 @@ export default util.createRule({ return; } - checkFunctionReturnType(node, options, sourceCode, loc => + checkFunctionReturnType(node, options, sourceCode, loc => { context.report({ node, loc, messageId: 'missingReturnType', - }), - ); + }); + }); }, FunctionDeclaration(node): void { if (isAllowedFunction(node)) { @@ -212,13 +212,13 @@ export default util.createRule({ return; } - checkFunctionReturnType(node, options, sourceCode, loc => + checkFunctionReturnType(node, options, sourceCode, loc => { context.report({ node, loc, messageId: 'missingReturnType', - }), - ); + }); + }); }, }; }, diff --git a/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts b/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts index d4a0efd56e54..1ff38c7efed2 100644 --- a/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts +++ b/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts @@ -212,8 +212,10 @@ export default util.createRule({ } return; - case AST_NODE_TYPES.TSParameterProperty: - return checkParameter(param.parameter); + case AST_NODE_TYPES.TSParameterProperty: { + checkParameter(param.parameter); + return; + } case AST_NODE_TYPES.AssignmentPattern: // ignored as it has a type via its assignment return; @@ -337,8 +339,10 @@ export default util.createRule({ switch (node.type) { case AST_NODE_TYPES.ArrowFunctionExpression: - case AST_NODE_TYPES.FunctionExpression: - return checkFunctionExpression(node); + case AST_NODE_TYPES.FunctionExpression: { + checkFunctionExpression(node); + return; + } case AST_NODE_TYPES.ArrayExpression: for (const element of node.elements) { @@ -353,7 +357,10 @@ export default util.createRule({ ) { return; } - return checkNode(node.value); + { + checkNode(node.value); + return; + } case AST_NODE_TYPES.ClassDeclaration: case AST_NODE_TYPES.ClassExpression: @@ -362,8 +369,10 @@ export default util.createRule({ } return; - case AST_NODE_TYPES.FunctionDeclaration: - return checkFunction(node); + case AST_NODE_TYPES.FunctionDeclaration: { + checkFunction(node); + return; + } case AST_NODE_TYPES.MethodDefinition: case AST_NODE_TYPES.TSAbstractMethodDefinition: @@ -373,10 +382,15 @@ export default util.createRule({ ) { return; } - return checkNode(node.value); + { + checkNode(node.value); + return; + } - case AST_NODE_TYPES.Identifier: - return followReference(node); + case AST_NODE_TYPES.Identifier: { + followReference(node); + return; + } case AST_NODE_TYPES.ObjectExpression: for (const property of node.properties) { @@ -384,11 +398,15 @@ export default util.createRule({ } return; - case AST_NODE_TYPES.Property: - return checkNode(node.value); + case AST_NODE_TYPES.Property: { + checkNode(node.value); + return; + } - case AST_NODE_TYPES.TSEmptyBodyFunctionExpression: - return checkEmptyBodyFunctionExpression(node); + case AST_NODE_TYPES.TSEmptyBodyFunctionExpression: { + checkEmptyBodyFunctionExpression(node); + return; + } case AST_NODE_TYPES.VariableDeclaration: for (const declaration of node.declarations) { @@ -396,8 +414,10 @@ export default util.createRule({ } return; - case AST_NODE_TYPES.VariableDeclarator: - return checkNode(node.init); + case AST_NODE_TYPES.VariableDeclarator: { + checkNode(node.init); + return; + } } } diff --git a/packages/eslint-plugin/src/rules/func-call-spacing.ts b/packages/eslint-plugin/src/rules/func-call-spacing.ts index b72c54951f92..143fe13ac8a9 100644 --- a/packages/eslint-plugin/src/rules/func-call-spacing.ts +++ b/packages/eslint-plugin/src/rules/func-call-spacing.ts @@ -109,7 +109,7 @@ export default util.createRule({ if (option === 'never') { if (hasWhitespace) { - return context.report({ + context.report({ node, loc: lastCalleeToken.loc.start, messageId: 'unexpectedWhitespace', @@ -132,6 +132,7 @@ export default util.createRule({ return null; }, }); + return; } } else if (isOptionalCall) { // disallow: diff --git a/packages/eslint-plugin/src/rules/indent.ts b/packages/eslint-plugin/src/rules/indent.ts index 94c1899f2d43..6e6f95da28a5 100644 --- a/packages/eslint-plugin/src/rules/indent.ts +++ b/packages/eslint-plugin/src/rules/indent.ts @@ -191,12 +191,12 @@ export default util.createRule({ return; } - return rules.VariableDeclaration(node); + rules.VariableDeclaration(node); }, TSAsExpression(node: TSESTree.TSAsExpression) { // transform it to a BinaryExpression - return rules['BinaryExpression, LogicalExpression']({ + rules['BinaryExpression, LogicalExpression']({ type: AST_NODE_TYPES.BinaryExpression, operator: 'as', left: node.expression, @@ -212,7 +212,7 @@ export default util.createRule({ TSConditionalType(node: TSESTree.TSConditionalType) { // transform it to a ConditionalExpression - return rules.ConditionalExpression({ + rules.ConditionalExpression({ type: AST_NODE_TYPES.ConditionalExpression, test: { parent: node, @@ -242,7 +242,7 @@ export default util.createRule({ node: TSESTree.TSEnumDeclaration | TSESTree.TSTypeLiteral, ) { // transform it to an ObjectExpression - return rules['ObjectExpression, ObjectPattern']({ + rules['ObjectExpression, ObjectPattern']({ type: AST_NODE_TYPES.ObjectExpression, properties: ( node.members as (TSESTree.TSEnumMember | TSESTree.TypeElement)[] @@ -263,7 +263,7 @@ export default util.createRule({ // use VariableDeclaration instead of ImportDeclaration because it's essentially the same thing const { id, moduleReference } = node; - return rules.VariableDeclaration({ + rules.VariableDeclaration({ type: AST_NODE_TYPES.VariableDeclaration, kind: 'const' as const, declarations: [ @@ -314,7 +314,7 @@ export default util.createRule({ TSIndexedAccessType(node: TSESTree.TSIndexedAccessType) { // convert to a MemberExpression - return rules['MemberExpression, JSXMemberExpression, MetaProperty']({ + rules['MemberExpression, JSXMemberExpression, MetaProperty']({ type: AST_NODE_TYPES.MemberExpression, object: node.objectType as any, property: node.indexType as any, @@ -330,7 +330,7 @@ export default util.createRule({ TSInterfaceBody(node: TSESTree.TSInterfaceBody) { // transform it to an ClassBody - return rules['BlockStatement, ClassBody']({ + rules['BlockStatement, ClassBody']({ type: AST_NODE_TYPES.ClassBody, body: node.body.map( p => @@ -351,9 +351,7 @@ export default util.createRule({ node: TSESTree.TSInterfaceDeclaration, ) { // transform it to a ClassDeclaration - return rules[ - 'ClassDeclaration[superClass], ClassExpression[superClass]' - ]({ + rules['ClassDeclaration[superClass], ClassExpression[superClass]']({ type: AST_NODE_TYPES.ClassDeclaration, body: node.body as any, id: null, @@ -381,7 +379,7 @@ export default util.createRule({ )!; // transform it to an ObjectExpression - return rules['ObjectExpression, ObjectPattern']({ + rules['ObjectExpression, ObjectPattern']({ type: AST_NODE_TYPES.ObjectExpression, properties: [ { @@ -420,7 +418,7 @@ export default util.createRule({ TSModuleBlock(node: TSESTree.TSModuleBlock) { // transform it to a BlockStatement - return rules['BlockStatement, ClassBody']({ + rules['BlockStatement, ClassBody']({ type: AST_NODE_TYPES.BlockStatement, body: node.body as any, @@ -432,7 +430,7 @@ export default util.createRule({ }, TSQualifiedName(node: TSESTree.TSQualifiedName) { - return rules['MemberExpression, JSXMemberExpression, MetaProperty']({ + rules['MemberExpression, JSXMemberExpression, MetaProperty']({ type: AST_NODE_TYPES.MemberExpression, object: node.left as any, property: node.right as any, @@ -448,7 +446,7 @@ export default util.createRule({ TSTupleType(node: TSESTree.TSTupleType) { // transform it to an ArrayExpression - return rules['ArrayExpression, ArrayPattern']({ + rules['ArrayExpression, ArrayPattern']({ type: AST_NODE_TYPES.ArrayExpression, elements: node.elementTypes as any, @@ -468,7 +466,7 @@ export default util.createRule({ // JSX is about the closest we can get because the angle brackets // it's not perfect but it works! - return rules.JSXOpeningElement({ + rules.JSXOpeningElement({ type: AST_NODE_TYPES.JSXOpeningElement, selfClosing: false, name: name as any, diff --git a/packages/eslint-plugin/src/rules/lines-around-comment.ts b/packages/eslint-plugin/src/rules/lines-around-comment.ts index f7cdef33b2e4..e052a12325a6 100644 --- a/packages/eslint-plugin/src/rules/lines-around-comment.ts +++ b/packages/eslint-plugin/src/rules/lines-around-comment.ts @@ -403,7 +403,7 @@ export default util.createRule({ } } } - return context.report(descriptor); + context.report(descriptor); }; const customContext = { report: customReport }; diff --git a/packages/eslint-plugin/src/rules/member-ordering.ts b/packages/eslint-plugin/src/rules/member-ordering.ts index 29b748e88cfe..b5ef0346f4cc 100644 --- a/packages/eslint-plugin/src/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/rules/member-ordering.ts @@ -832,7 +832,7 @@ export default util.createRule({ i && isMemberOptional(member) !== isMemberOptional(members[i - 1]), ); - const report = (member: Member): void => + const report = (member: Member): void => { context.report({ messageId: 'incorrectRequiredMembersOrder', loc: member.loc, @@ -842,6 +842,7 @@ export default util.createRule({ optionalityOrder === 'required-first' ? 'required' : 'optional', }, }); + }; // if the optionality of the first item is correct (based on optionalityOrder) // then the first 0 inclusive to switchIndex exclusive members all diff --git a/packages/eslint-plugin/src/rules/naming-convention-utils/format.ts b/packages/eslint-plugin/src/rules/naming-convention-utils/format.ts index d3db62399eaa..b74b1b688a5a 100644 --- a/packages/eslint-plugin/src/rules/naming-convention-utils/format.ts +++ b/packages/eslint-plugin/src/rules/naming-convention-utils/format.ts @@ -17,26 +17,26 @@ https://gist.github.com/mathiasbynens/6334847 function isPascalCase(name: string): boolean { return ( name.length === 0 || - (name[0] === name[0].toUpperCase() && !name.includes('_')) + (name.startsWith(name[0].toUpperCase()) && !name.includes('_')) ); } function isStrictPascalCase(name: string): boolean { return ( name.length === 0 || - (name[0] === name[0].toUpperCase() && hasStrictCamelHumps(name, true)) + (name.startsWith(name[0].toUpperCase()) && hasStrictCamelHumps(name, true)) ); } function isCamelCase(name: string): boolean { return ( name.length === 0 || - (name[0] === name[0].toLowerCase() && !name.includes('_')) + (name.startsWith(name[0].toLowerCase()) && !name.includes('_')) ); } function isStrictCamelCase(name: string): boolean { return ( name.length === 0 || - (name[0] === name[0].toLowerCase() && hasStrictCamelHumps(name, false)) + (name.startsWith(name[0].toLowerCase()) && hasStrictCamelHumps(name, false)) ); } diff --git a/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts b/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts index ab6f08c1bb55..f4f115c297d4 100644 --- a/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts +++ b/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts @@ -105,16 +105,17 @@ export default util.createRule({ if (options.ignoreVoidOperator) { // handle wrapping with `void` - return context.report({ + context.report({ node, messageId: 'invalidVoidExprArrowWrapVoid', fix: wrapVoidFix, }); + return; } // handle wrapping with braces const arrowFunction = invalidAncestor; - return context.report({ + context.report({ node, messageId: 'invalidVoidExprArrow', fix(fixer) { @@ -138,6 +139,7 @@ export default util.createRule({ return fixer.replaceText(arrowBody, newArrowBodyText); }, }); + return; } if (invalidAncestor.type === AST_NODE_TYPES.ReturnStatement) { @@ -145,18 +147,19 @@ export default util.createRule({ if (options.ignoreVoidOperator) { // handle wrapping with `void` - return context.report({ + context.report({ node, messageId: 'invalidVoidExprReturnWrapVoid', fix: wrapVoidFix, }); + return; } const returnStmt = invalidAncestor; if (isFinalReturn(returnStmt)) { // remove the `return` keyword - return context.report({ + context.report({ node, messageId: 'invalidVoidExprReturnLast', fix(fixer) { @@ -170,10 +173,11 @@ export default util.createRule({ return fixer.replaceText(returnStmt, newReturnStmtText); }, }); + return; } // move before the `return` keyword - return context.report({ + context.report({ node, messageId: 'invalidVoidExprReturn', fix(fixer) { @@ -192,16 +196,18 @@ export default util.createRule({ return fixer.replaceText(returnStmt, newReturnStmtText); }, }); + return; } // handle generic case if (options.ignoreVoidOperator) { // this would be reported by this rule btw. such irony - return context.report({ + context.report({ node, messageId: 'invalidVoidExprWrapVoid', suggest: [{ messageId: 'voidExprWrapVoid', fix: wrapVoidFix }], }); + return; } context.report({ diff --git a/packages/eslint-plugin/src/rules/no-dupe-class-members.ts b/packages/eslint-plugin/src/rules/no-dupe-class-members.ts index 95689cae513c..979161914baf 100644 --- a/packages/eslint-plugin/src/rules/no-dupe-class-members.ts +++ b/packages/eslint-plugin/src/rules/no-dupe-class-members.ts @@ -40,7 +40,7 @@ export default util.createRule({ return; } - return coreListener(node); + coreListener(node); }; } diff --git a/packages/eslint-plugin/src/rules/no-duplicate-type-constituents.ts b/packages/eslint-plugin/src/rules/no-duplicate-type-constituents.ts index 85135d5c7c5b..c6e31acf5864 100644 --- a/packages/eslint-plugin/src/rules/no-duplicate-type-constituents.ts +++ b/packages/eslint-plugin/src/rules/no-duplicate-type-constituents.ts @@ -108,7 +108,7 @@ export default util.createRule({ function checkDuplicate( node: TSESTree.TSIntersectionType | TSESTree.TSUnionType, ): void { - const cachedTypeMap: Map = new Map(); + const cachedTypeMap = new Map(); node.types.reduce( (uniqueConstituents, constituentNode) => { const duplicatedPreviousConstituentInAst = uniqueConstituents.find( diff --git a/packages/eslint-plugin/src/rules/no-extra-parens.ts b/packages/eslint-plugin/src/rules/no-extra-parens.ts index b3a150ad201e..535d319920bd 100644 --- a/packages/eslint-plugin/src/rules/no-extra-parens.ts +++ b/packages/eslint-plugin/src/rules/no-extra-parens.ts @@ -41,25 +41,27 @@ export default util.createRule({ return; // ignore } if (isLeftTypeAssertion) { - return rule({ + rule({ ...node, left: { ...node.left, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } if (isRightTypeAssertion) { - return rule({ + rule({ ...node, right: { ...node.right, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rule(node); + rule(node); } function callExp( node: TSESTree.CallExpression | TSESTree.NewExpression, @@ -68,13 +70,14 @@ export default util.createRule({ if (util.isTypeAssertion(node.callee)) { // reduces the precedence of the node so the rule thinks it needs to be wrapped - return rule({ + rule({ ...node, callee: { ...node.callee, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } if ( @@ -85,7 +88,7 @@ export default util.createRule({ param.type === AST_NODE_TYPES.TSArrayType, ) ) { - return rule({ + rule({ ...node, arguments: [ { @@ -94,9 +97,10 @@ export default util.createRule({ }, ], }); + return; } - return rule(node); + rule(node); } function unaryUpdateExpression( node: TSESTree.UnaryExpression | TSESTree.UpdateExpression, @@ -105,125 +109,137 @@ export default util.createRule({ if (util.isTypeAssertion(node.argument)) { // reduces the precedence of the node so the rule thinks it needs to be wrapped - return rule({ + rule({ ...node, argument: { ...node.argument, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rule(node); + rule(node); } const overrides: TSESLint.RuleListener = { // ArrayExpression ArrowFunctionExpression(node) { if (!util.isTypeAssertion(node.body)) { - return rules.ArrowFunctionExpression(node); + rules.ArrowFunctionExpression(node); + return; } }, // AssignmentExpression AwaitExpression(node) { if (util.isTypeAssertion(node.argument)) { // reduces the precedence of the node so the rule thinks it needs to be wrapped - return rules.AwaitExpression({ + rules.AwaitExpression({ ...node, argument: { ...node.argument, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rules.AwaitExpression(node); + rules.AwaitExpression(node); }, BinaryExpression: binaryExp, CallExpression: callExp, ClassDeclaration(node) { if (node.superClass?.type === AST_NODE_TYPES.TSAsExpression) { - return rules.ClassDeclaration({ + rules.ClassDeclaration({ ...node, superClass: { ...node.superClass, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rules.ClassDeclaration(node); + rules.ClassDeclaration(node); }, ClassExpression(node) { if (node.superClass?.type === AST_NODE_TYPES.TSAsExpression) { - return rules.ClassExpression({ + rules.ClassExpression({ ...node, superClass: { ...node.superClass, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rules.ClassExpression(node); + rules.ClassExpression(node); }, ConditionalExpression(node) { // reduces the precedence of the node so the rule thinks it needs to be wrapped if (util.isTypeAssertion(node.test)) { - return rules.ConditionalExpression({ + rules.ConditionalExpression({ ...node, test: { ...node.test, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } if (util.isTypeAssertion(node.consequent)) { - return rules.ConditionalExpression({ + rules.ConditionalExpression({ ...node, consequent: { ...node.consequent, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } if (util.isTypeAssertion(node.alternate)) { // reduces the precedence of the node so the rule thinks it needs to be wrapped - return rules.ConditionalExpression({ + rules.ConditionalExpression({ ...node, alternate: { ...node.alternate, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rules.ConditionalExpression(node); + rules.ConditionalExpression(node); }, // DoWhileStatement // ForIn and ForOf are guarded by eslint version ForStatement(node) { // make the rule skip the piece by removing it entirely if (node.init && util.isTypeAssertion(node.init)) { - return rules.ForStatement({ + rules.ForStatement({ ...node, init: null, }); + return; } if (node.test && util.isTypeAssertion(node.test)) { - return rules.ForStatement({ + rules.ForStatement({ ...node, test: null, }); + return; } if (node.update && util.isTypeAssertion(node.update)) { - return rules.ForStatement({ + rules.ForStatement({ ...node, update: null, }); + return; } - return rules.ForStatement(node); + rules.ForStatement(node); }, 'ForStatement > *.init:exit'(node: TSESTree.Node) { if (!util.isTypeAssertion(node)) { - return rules['ForStatement > *.init:exit'](node); + rules['ForStatement > *.init:exit'](node); + return; } }, // IfStatement @@ -231,16 +247,17 @@ export default util.createRule({ MemberExpression(node) { if (util.isTypeAssertion(node.object)) { // reduces the precedence of the node so the rule thinks it needs to be wrapped - return rules.MemberExpression({ + rules.MemberExpression({ ...node, object: { ...node.object, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rules.MemberExpression(node); + rules.MemberExpression(node); }, NewExpression: callExp, // ObjectExpression @@ -248,18 +265,21 @@ export default util.createRule({ // SequenceExpression SpreadElement(node) { if (!util.isTypeAssertion(node.argument)) { - return rules.SpreadElement(node); + rules.SpreadElement(node); + return; } }, SwitchCase(node) { if (node.test && !util.isTypeAssertion(node.test)) { - return rules.SwitchCase(node); + rules.SwitchCase(node); + return; } }, // SwitchStatement ThrowStatement(node) { if (node.argument && !util.isTypeAssertion(node.argument)) { - return rules.ThrowStatement(node); + rules.ThrowStatement(node); + return; } }, UnaryExpression: unaryUpdateExpression, @@ -269,7 +289,8 @@ export default util.createRule({ // WithStatement - i'm not going to even bother implementing this terrible and never used feature YieldExpression(node) { if (node.argument && !util.isTypeAssertion(node.argument)) { - return rules.YieldExpression(node); + rules.YieldExpression(node); + return; } }, }; @@ -281,12 +302,12 @@ export default util.createRule({ return; } - return rules.ForInStatement(node); + rules.ForInStatement(node); }; overrides.ForOfStatement = function (node): void { if (util.isTypeAssertion(node.right)) { // makes the rule skip checking of the right - return rules.ForOfStatement({ + rules.ForOfStatement({ ...node, type: AST_NODE_TYPES.ForOfStatement, right: { @@ -294,9 +315,10 @@ export default util.createRule({ type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rules.ForOfStatement(node); + rules.ForOfStatement(node); }; } else { overrides['ForInStatement, ForOfStatement'] = function ( @@ -304,7 +326,7 @@ export default util.createRule({ ): void { if (util.isTypeAssertion(node.right)) { // makes the rule skip checking of the right - return rules['ForInStatement, ForOfStatement']({ + rules['ForInStatement, ForOfStatement']({ ...node, type: AST_NODE_TYPES.ForOfStatement as any, right: { @@ -312,9 +334,10 @@ export default util.createRule({ type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rules['ForInStatement, ForOfStatement'](node); + rules['ForInStatement, ForOfStatement'](node); }; } return Object.assign({}, rules, overrides); diff --git a/packages/eslint-plugin/src/rules/no-restricted-imports.ts b/packages/eslint-plugin/src/rules/no-restricted-imports.ts index 17e93f7febaa..35c0174207eb 100644 --- a/packages/eslint-plugin/src/rules/no-restricted-imports.ts +++ b/packages/eslint-plugin/src/rules/no-restricted-imports.ts @@ -183,7 +183,7 @@ export default createRule({ } const restrictedPaths = getRestrictedPaths(options); - const allowedTypeImportPathNameSet: Set = new Set(); + const allowedTypeImportPathNameSet = new Set(); for (const restrictedPath of restrictedPaths) { if ( typeof restrictedPath === 'object' && @@ -227,10 +227,12 @@ export default createRule({ !isAllowedTypeImportPath(importSource) && !isAllowedTypeImportPattern(importSource) ) { - return rules.ImportDeclaration(node); + rules.ImportDeclaration(node); + return; } } else { - return rules.ImportDeclaration(node); + rules.ImportDeclaration(node); + return; } }, 'ExportNamedDeclaration[source]'( @@ -244,10 +246,12 @@ export default createRule({ !isAllowedTypeImportPath(importSource) && !isAllowedTypeImportPattern(importSource) ) { - return rules.ExportNamedDeclaration(node); + rules.ExportNamedDeclaration(node); + return; } } else { - return rules.ExportNamedDeclaration(node); + rules.ExportNamedDeclaration(node); + return; } }, ExportAllDeclaration: rules.ExportAllDeclaration, diff --git a/packages/eslint-plugin/src/rules/no-type-alias.ts b/packages/eslint-plugin/src/rules/no-type-alias.ts index cc568a6fa9db..8ed31e5f073b 100644 --- a/packages/eslint-plugin/src/rules/no-type-alias.ts +++ b/packages/eslint-plugin/src/rules/no-type-alias.ts @@ -188,16 +188,17 @@ export default util.createRule({ type: string, ): void { if (isRoot) { - return context.report({ + context.report({ node, messageId: 'noTypeAlias', data: { alias: type.toLowerCase(), }, }); + return; } - return context.report({ + context.report({ node, messageId: 'noCompositionAlias', data: { diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts index 007a8a07a6d6..5ec8ac5d674b 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts @@ -199,7 +199,8 @@ export default createRule({ node.type === AST_NODE_TYPES.UnaryExpression && node.operator === '!' ) { - return checkNode(node.argument, true); + checkNode(node.argument, true); + return; } // Since typescript array index signature types don't represent the @@ -219,7 +220,8 @@ export default createRule({ node.type === AST_NODE_TYPES.LogicalExpression && node.operator !== '??' ) { - return checkNode(node.right); + checkNode(node.right); + return; } const type = getConstrainedTypeAtLocation(services, node); @@ -435,7 +437,8 @@ export default createRule({ // Two special cases, where we can directly check the node that's returned: // () => something if (callback.body.type !== AST_NODE_TYPES.BlockStatement) { - return checkNode(callback.body); + checkNode(callback.body); + return; } // () => { return something; } const callbackBody = callback.body.body; @@ -444,7 +447,8 @@ export default createRule({ callbackBody[0].type === AST_NODE_TYPES.ReturnStatement && callbackBody[0].argument ) { - return checkNode(callbackBody[0].argument); + checkNode(callbackBody[0].argument); + return; } // Potential enhancement: could use code-path analysis to check // any function with a single return statement @@ -465,16 +469,18 @@ export default createRule({ return; } if (!returnTypes.some(isPossiblyFalsy)) { - return context.report({ + context.report({ node: callback, messageId: 'alwaysTruthyFunc', }); + return; } if (!returnTypes.some(isPossiblyTruthy)) { - return context.report({ + context.report({ node: callback, messageId: 'alwaysFalsyFunc', }); + return; } } } @@ -657,10 +663,14 @@ export default createRule({ AssignmentExpression: checkAssignmentExpression, BinaryExpression: checkIfBinaryExpressionIsNecessaryConditional, CallExpression: checkCallExpression, - ConditionalExpression: (node): void => checkNode(node.test), + ConditionalExpression: (node): void => { + checkNode(node.test); + }, DoWhileStatement: checkIfLoopIsNecessaryConditional, ForStatement: checkIfLoopIsNecessaryConditional, - IfStatement: (node): void => checkNode(node.test), + IfStatement: (node): void => { + checkNode(node.test); + }, LogicalExpression: checkLogicalExpressionForUnnecessaryConditionals, WhileStatement: checkIfLoopIsNecessaryConditional, 'MemberExpression[optional = true]': checkOptionalMemberExpression, diff --git a/packages/eslint-plugin/src/rules/no-unsafe-return.ts b/packages/eslint-plugin/src/rules/no-unsafe-return.ts index 93a1226e9e4a..cb110f523e43 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-return.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-return.ts @@ -137,13 +137,14 @@ export default util.createRule({ } // If the function return type was not unknown/unknown[], mark usage as unsafeReturn. - return context.report({ + context.report({ node: reportingNode, messageId, data: { type: anyType === util.AnyType.Any ? 'any' : 'any[]', }, }); + return; } for (const signature of functionType.getCallSignatures()) { @@ -159,7 +160,7 @@ export default util.createRule({ } const { sender, receiver } = result; - return context.report({ + context.report({ node: reportingNode, messageId: 'unsafeReturnAssignment', data: { @@ -167,6 +168,7 @@ export default util.createRule({ receiver: checker.typeToString(receiver), }, }); + return; } } diff --git a/packages/eslint-plugin/src/rules/padding-line-between-statements.ts b/packages/eslint-plugin/src/rules/padding-line-between-statements.ts index ad7852337c32..d2342adc8699 100644 --- a/packages/eslint-plugin/src/rules/padding-line-between-statements.ts +++ b/packages/eslint-plugin/src/rules/padding-line-between-statements.ts @@ -438,12 +438,9 @@ function verifyForAlways( messageId: 'expectedBlankLine', fix(fixer) { const sourceCode = context.getSourceCode(); - let prevToken = getActualLastToken( - prevNode, - sourceCode, - ) as TSESTree.Token; + let prevToken = getActualLastToken(prevNode, sourceCode)!; const nextToken = - (sourceCode.getFirstTokenBetween(prevToken, nextNode, { + sourceCode.getFirstTokenBetween(prevToken, nextNode, { includeComments: true, /** @@ -473,7 +470,7 @@ function verifyForAlways( } return true; }, - }) as TSESTree.Token) || nextNode; + })! || nextNode; const insertText = util.isTokenOnSameLine(prevToken, nextToken) ? '\n\n' : '\n'; diff --git a/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts b/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts index 8e61a735c13e..737761bb8366 100644 --- a/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts +++ b/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts @@ -124,7 +124,7 @@ export default createRule({ } catch { return; } - return context.report({ + context.report({ node: memberNode.property, messageId: 'regExpExecOverStringMatch', fix: getWrappingFixer({ @@ -134,6 +134,7 @@ export default createRule({ wrap: objectCode => `${regExp.toString()}.exec(${objectCode})`, }), }); + return; } const argumentType = services.getTypeAtLocation(argumentNode); @@ -141,8 +142,8 @@ export default createRule({ tsutils.unionTypeParts(argumentType), ); switch (argumentTypes) { - case ArgumentType.RegExp: - return context.report({ + case ArgumentType.RegExp: { + context.report({ node: memberNode.property, messageId: 'regExpExecOverStringMatch', fix: getWrappingFixer({ @@ -153,9 +154,11 @@ export default createRule({ `${argumentCode}.exec(${objectCode})`, }), }); + return; + } - case ArgumentType.String: - return context.report({ + case ArgumentType.String: { + context.report({ node: memberNode.property, messageId: 'regExpExecOverStringMatch', fix: getWrappingFixer({ @@ -166,6 +169,8 @@ export default createRule({ `RegExp(${argumentCode}).exec(${objectCode})`, }), }); + return; + } } }, }; diff --git a/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts b/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts index d6afab60146d..f296bb3dfdc7 100644 --- a/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts +++ b/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts @@ -84,8 +84,7 @@ export default createRule({ return ( evaluated != null && typeof evaluated.value === 'string' && - // checks if the string is a character long - evaluated.value[0] === evaluated.value + evaluated.value.length === 1 ); } diff --git a/packages/eslint-plugin/src/rules/promise-function-async.ts b/packages/eslint-plugin/src/rules/promise-function-async.ts index ba671d5929b0..17d1d2c2a040 100644 --- a/packages/eslint-plugin/src/rules/promise-function-async.ts +++ b/packages/eslint-plugin/src/rules/promise-function-async.ts @@ -137,11 +137,12 @@ export default util.createRule({ util.isTypeFlagSet(returnType, ts.TypeFlags.Any | ts.TypeFlags.Unknown) ) { // Report without auto fixer because the return type is unknown - return context.report({ + context.report({ messageId: 'missingAsync', node, loc: util.getFunctionHeadLoc(node, sourceCode), }); + return; } context.report({ diff --git a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts index 6d2cc2222eaa..069111981700 100644 --- a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts +++ b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts @@ -204,7 +204,7 @@ export default util.createRule({ isTypeFlagSetInUnion(baseType, ts.TypeFlags.StringLike) && isTypeFlagSetInUnion(otherType, ts.TypeFlags.NumberLike) ) { - return context.report({ + context.report({ data: { stringLike, left: typeChecker.typeToString(leftType), @@ -213,13 +213,14 @@ export default util.createRule({ messageId: 'mismatched', node, }); + return; } if ( isTypeFlagSetInUnion(baseType, ts.TypeFlags.NumberLike) && isTypeFlagSetInUnion(otherType, ts.TypeFlags.BigIntLike) ) { - return context.report({ + context.report({ data: { left: typeChecker.typeToString(leftType), right: typeChecker.typeToString(rightType), @@ -227,6 +228,7 @@ export default util.createRule({ messageId: 'bigintAndNumber', node, }); + return; } } } diff --git a/packages/eslint-plugin/src/rules/sort-type-constituents.ts b/packages/eslint-plugin/src/rules/sort-type-constituents.ts index ec54153e988d..cae6ff9d7401 100644 --- a/packages/eslint-plugin/src/rules/sort-type-constituents.ts +++ b/packages/eslint-plugin/src/rules/sort-type-constituents.ts @@ -233,7 +233,7 @@ export default util.createRule({ return fixer.replaceText(node, sorted); }; - return context.report({ + context.report({ node, messageId, data, @@ -250,6 +250,7 @@ export default util.createRule({ } : { fix }), }); + return; } } } diff --git a/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts b/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts index 45604ee8e0ea..6abdbf27fc6e 100644 --- a/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts +++ b/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts @@ -116,7 +116,7 @@ export default createRule({ if (discriminantType.isUnion()) { const unionTypes = tsutils.unionTypeParts(discriminantType); - const caseTypes: Set = new Set(); + const caseTypes = new Set(); for (const switchCase of node.cases) { if (switchCase.test == null) { // Switch has 'default' branch - do nothing. diff --git a/packages/eslint-plugin/src/util/astUtils.ts b/packages/eslint-plugin/src/util/astUtils.ts index a4bf10251cd3..c104a5b6476d 100644 --- a/packages/eslint-plugin/src/util/astUtils.ts +++ b/packages/eslint-plugin/src/util/astUtils.ts @@ -56,7 +56,7 @@ export function forEachReturnStatement( function traverse(node: ts.Node): T | undefined { switch (node.kind) { case ts.SyntaxKind.ReturnStatement: - return visitor(node); + return visitor(node as ts.ReturnStatement); case ts.SyntaxKind.CaseBlock: case ts.SyntaxKind.Block: case ts.SyntaxKind.IfStatement: diff --git a/packages/eslint-plugin/src/util/collectUnusedVariables.ts b/packages/eslint-plugin/src/util/collectUnusedVariables.ts index 4d1b62b42341..05b158ef44ff 100644 --- a/packages/eslint-plugin/src/util/collectUnusedVariables.ts +++ b/packages/eslint-plugin/src/util/collectUnusedVariables.ts @@ -437,7 +437,7 @@ function isExported(variable: TSESLint.Scope.Variable): boolean { return false; } - return node.parent!.type.indexOf('Export') === 0; + return node.parent!.type.startsWith('Export'); } return false; } diff --git a/packages/eslint-plugin/tests/configs.test.ts b/packages/eslint-plugin/tests/configs.test.ts index 07e204e1344a..321b9792f8c0 100644 --- a/packages/eslint-plugin/tests/configs.test.ts +++ b/packages/eslint-plugin/tests/configs.test.ts @@ -130,7 +130,7 @@ describe('recommended-type-checked.ts', () => { describe('strict.ts', () => { const unfilteredConfigRules: Record = - plugin.configs['strict'].rules; + plugin.configs.strict.rules; it('contains all strict rules, excluding type checked ones', () => { const configRules = filterRules(unfilteredConfigRules); @@ -166,7 +166,7 @@ describe('strict-type-checked.ts', () => { describe('stylistic.ts', () => { const unfilteredConfigRules: Record = - plugin.configs['stylistic'].rules; + plugin.configs.stylistic.rules; it('contains all stylistic rules, excluding deprecated or type checked ones', () => { const configRules = filterRules(unfilteredConfigRules); diff --git a/packages/eslint-plugin/tests/docs.test.ts b/packages/eslint-plugin/tests/docs.test.ts index a2bef8cac839..5f912169edb0 100644 --- a/packages/eslint-plugin/tests/docs.test.ts +++ b/packages/eslint-plugin/tests/docs.test.ts @@ -94,9 +94,9 @@ describe('Validating rule docs', () => { // Get all H2 headers objects as the other levels are variable by design. const headers = tokens.filter(tokenIsH2); - headers.forEach(header => - expect(header.text).toBe(titleCase(header.text)), - ); + headers.forEach(header => { + expect(header.text).toBe(titleCase(header.text)); + }); }); const importantHeadings = new Set([ diff --git a/packages/eslint-plugin/tools/generate-configs.ts b/packages/eslint-plugin/tools/generate-configs.ts index 5056bdb7de42..8fac06d16687 100644 --- a/packages/eslint-plugin/tools/generate-configs.ts +++ b/packages/eslint-plugin/tools/generate-configs.ts @@ -47,9 +47,7 @@ async function main(): Promise { const prettierConfig = prettier.resolveConfig.sync(__dirname); - interface LinterConfigRules { - [name: string]: TSESLint.Linter.RuleLevel; - } + type LinterConfigRules = Record; interface LinterConfig extends TSESLint.Linter.Config { extends?: string[] | string; diff --git a/packages/rule-schema-to-typescript-types/src/index.ts b/packages/rule-schema-to-typescript-types/src/index.ts index 43d16826ab30..ef1e187c2a6f 100644 --- a/packages/rule-schema-to-typescript-types/src/index.ts +++ b/packages/rule-schema-to-typescript-types/src/index.ts @@ -69,9 +69,7 @@ function compileSchema( const refMap = new Map(); // we only support defs at the top level for simplicity - const defs = (schema.$defs ?? schema.definitions) as - | Record - | undefined; + const defs = schema.$defs ?? schema.definitions; if (defs) { for (const [defKey, defSchema] of Object.entries(defs)) { const typeName = toPascalCase(defKey); diff --git a/packages/rule-tester/src/RuleTester.ts b/packages/rule-tester/src/RuleTester.ts index cc6577611378..e72f42dacd37 100644 --- a/packages/rule-tester/src/RuleTester.ts +++ b/packages/rule-tester/src/RuleTester.ts @@ -530,10 +530,9 @@ export class RuleTester extends TestFramework { if (ajv.errors) { const errors = ajv.errors .map(error => { - const field = - error.dataPath[0] === '.' - ? error.dataPath.slice(1) - : error.dataPath; + const field = error.dataPath.startsWith('.') + ? error.dataPath.slice(1) + : error.dataPath; return `\t${field}: ${error.message}`; }) diff --git a/packages/rule-tester/src/types/DependencyConstraint.ts b/packages/rule-tester/src/types/DependencyConstraint.ts index ecb86e912cdb..f02f51c4583a 100644 --- a/packages/rule-tester/src/types/DependencyConstraint.ts +++ b/packages/rule-tester/src/types/DependencyConstraint.ts @@ -12,9 +12,4 @@ export type AtLeastVersionConstraint = export type VersionConstraint = | AtLeastVersionConstraint | SemverVersionConstraint; -export interface DependencyConstraint { - /** - * Passing a string for the value is shorthand for a '>=' constraint - */ - readonly [packageName: string]: VersionConstraint; -} +export type DependencyConstraint = Readonly>; diff --git a/packages/rule-tester/src/utils/config-validator.ts b/packages/rule-tester/src/utils/config-validator.ts index ef88f7e664eb..816aed3f4c41 100644 --- a/packages/rule-tester/src/utils/config-validator.ts +++ b/packages/rule-tester/src/utils/config-validator.ts @@ -227,8 +227,9 @@ function formatErrors(errors: AjvErrorObject[]): string { return `Property "${formattedField}" is the wrong type (expected ${formattedExpectedType} but got \`${formattedValue}\`)`; } - const field = - error.dataPath[0] === '.' ? error.dataPath.slice(1) : error.dataPath; + const field = error.dataPath.startsWith('.') + ? error.dataPath.slice(1) + : error.dataPath; return `"${field}" ${error.message}. Value: ${JSON.stringify( error.data, diff --git a/packages/rule-tester/src/utils/validationHelpers.ts b/packages/rule-tester/src/utils/validationHelpers.ts index 33fd0c234de8..1156c9968f59 100644 --- a/packages/rule-tester/src/utils/validationHelpers.ts +++ b/packages/rule-tester/src/utils/validationHelpers.ts @@ -111,10 +111,16 @@ export function wrapParser(parser: Linter.ParserModule): Linter.ParserModule { simpleTraverse(ast, { visitorKeys: visitorKeys, - enter: node => defineStartEndAsError('node', node), + enter: node => { + defineStartEndAsError('node', node); + }, + }); + ast.tokens?.forEach(token => { + defineStartEndAsError('token', token); + }); + ast.comments?.forEach(comment => { + defineStartEndAsError('token', comment); }); - ast.tokens?.forEach(token => defineStartEndAsError('token', token)); - ast.comments?.forEach(comment => defineStartEndAsError('token', comment)); } if ('parseForESLint' in parser) { diff --git a/packages/rule-tester/tests/RuleTester.test.ts b/packages/rule-tester/tests/RuleTester.test.ts index 93f9f6d35d24..ec2c65e5af73 100644 --- a/packages/rule-tester/tests/RuleTester.test.ts +++ b/packages/rule-tester/tests/RuleTester.test.ts @@ -60,7 +60,9 @@ jest.mock('@typescript-eslint/parser', () => { /* eslint-disable jest/prefer-spy-on -- we need to specifically assign to the properties or else it will use the global value and register actual tests! */ -const IMMEDIATE_CALLBACK: RuleTesterTestFrameworkFunctionBase = (_, cb) => cb(); +const IMMEDIATE_CALLBACK: RuleTesterTestFrameworkFunctionBase = (_, cb) => { + cb(); +}; RuleTester.afterAll = jest.fn(/* intentionally don't immediate callback here */); RuleTester.describe = jest.fn(IMMEDIATE_CALLBACK); @@ -305,7 +307,7 @@ describe('RuleTester', () => { }, }); - expect(() => + expect(() => { ruleTester.run('my-rule', NOOP_RULE, { valid: [ { @@ -315,8 +317,8 @@ describe('RuleTester', () => { ], invalid: [], - }), - ).toThrowErrorMatchingInlineSnapshot( + }); + }).toThrowErrorMatchingInlineSnapshot( `"Do not set the parser at the test level unless you want to use a parser other than "@typescript-eslint/parser""`, ); }); diff --git a/packages/scope-manager/src/referencer/ClassVisitor.ts b/packages/scope-manager/src/referencer/ClassVisitor.ts index 6123ab15e794..46e729a539de 100644 --- a/packages/scope-manager/src/referencer/ClassVisitor.ts +++ b/packages/scope-manager/src/referencer/ClassVisitor.ts @@ -57,7 +57,9 @@ class ClassVisitor extends Visitor { .defineIdentifier(node.id, new ClassNameDefinition(node.id, node)); } - node.decorators.forEach(d => this.#referencer.visit(d)); + node.decorators.forEach(d => { + this.#referencer.visit(d); + }); this.#referencer.scopeManager.nestClassScope(node); @@ -75,7 +77,9 @@ class ClassVisitor extends Visitor { this.visitType(node.typeParameters); // then the usages this.visitType(node.superTypeArguments); - node.implements?.forEach(imp => this.visitType(imp)); + node.implements?.forEach(imp => { + this.visitType(imp); + }); this.visit(node.body); @@ -219,7 +223,9 @@ class ClassVisitor extends Visitor { { processRightHandNodes: true }, ); this.visitFunctionParameterTypeAnnotation(param, withMethodDecorators); - param.decorators.forEach(d => this.visit(d)); + param.decorators.forEach(d => { + this.visit(d); + }); } this.visitMetadataType(node.returnType, withMethodDecorators); @@ -271,7 +277,9 @@ class ClassVisitor extends Visitor { } } - node.decorators.forEach(d => this.#referencer.visit(d)); + node.decorators.forEach(d => { + this.#referencer.visit(d); + }); } protected visitMethod(node: TSESTree.MethodDefinition): void { @@ -285,7 +293,9 @@ class ClassVisitor extends Visitor { this.#referencer.visit(node.value); } - node.decorators.forEach(d => this.#referencer.visit(d)); + node.decorators.forEach(d => { + this.#referencer.visit(d); + }); } protected visitType(node: TSESTree.Node | null | undefined): void { @@ -389,7 +399,9 @@ class ClassVisitor extends Visitor { protected StaticBlock(node: TSESTree.StaticBlock): void { this.#referencer.scopeManager.nestClassStaticBlockScope(node); - node.body.forEach(b => this.visit(b)); + node.body.forEach(b => { + this.visit(b); + }); this.#referencer.close(node); } diff --git a/packages/scope-manager/src/referencer/Referencer.ts b/packages/scope-manager/src/referencer/Referencer.ts index 38e4a0d2adac..a5c1f55fbb6c 100644 --- a/packages/scope-manager/src/referencer/Referencer.ts +++ b/packages/scope-manager/src/referencer/Referencer.ts @@ -269,7 +269,9 @@ class Referencer extends Visitor { { processRightHandNodes: true }, ); this.visitFunctionParameterTypeAnnotation(param); - param.decorators.forEach(d => this.visit(d)); + param.decorators.forEach(d => { + this.visit(d); + }); } this.visitType(node.returnType); diff --git a/packages/scope-manager/src/scope/ScopeBase.ts b/packages/scope-manager/src/scope/ScopeBase.ts index e107c7d90570..fb5110297368 100644 --- a/packages/scope-manager/src/scope/ScopeBase.ts +++ b/packages/scope-manager/src/scope/ScopeBase.ts @@ -232,7 +232,7 @@ abstract class ScopeBase< block: TBlock, isMethodDefinition: boolean, ) { - const upperScopeAsScopeBase = upperScope as Scope; + const upperScopeAsScopeBase = upperScope!; this.type = type; this.#dynamic = @@ -371,7 +371,9 @@ abstract class ScopeBase< // Try Resolving all references in this scope. assert(this.leftToResolve); - this.leftToResolve.forEach(ref => closeRef(ref, scopeManager)); + this.leftToResolve.forEach(ref => { + closeRef(ref, scopeManager); + }); this.leftToResolve = null; return this.upper; @@ -386,7 +388,7 @@ abstract class ScopeBase< } protected delegateToUpperScope(ref: Reference): void { - const upper = this.upper as Scope as AnyScope; + const upper = this.upper! as AnyScope; if (upper?.leftToResolve) { upper.leftToResolve.push(ref); } diff --git a/packages/scope-manager/src/scope/WithScope.ts b/packages/scope-manager/src/scope/WithScope.ts index 7058ab70faa5..9ab1a377697b 100644 --- a/packages/scope-manager/src/scope/WithScope.ts +++ b/packages/scope-manager/src/scope/WithScope.ts @@ -23,7 +23,9 @@ class WithScope extends ScopeBase< return super.close(scopeManager); } assert(this.leftToResolve); - this.leftToResolve.forEach(ref => this.delegateToUpperScope(ref)); + this.leftToResolve.forEach(ref => { + this.delegateToUpperScope(ref); + }); this.leftToResolve = null; return this.upper; } diff --git a/packages/scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts b/packages/scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts index 14cfeceb368d..5054bba01d39 100644 --- a/packages/scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts +++ b/packages/scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts @@ -24,8 +24,8 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(1); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('array'); + expect(scope.implicit.leftToBeResolved).toHaveLength(1); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -64,8 +64,8 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(1); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('array'); + expect(scope.implicit.leftToBeResolved).toHaveLength(1); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('array'); scope = scopeManager.scopes[2]; variables = getRealVariables(scope.variables); @@ -104,9 +104,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(2); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('d'); - expect(scope['implicit'].leftToBeResolved[1].identifier.name).toBe('array'); + expect(scope.implicit.leftToBeResolved).toHaveLength(2); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('d'); + expect(scope.implicit.leftToBeResolved[1].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -154,11 +154,11 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(2); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('d'); - expectToBeForScope(scope['implicit'].leftToBeResolved[0].from); - expect(scope['implicit'].leftToBeResolved[1].identifier.name).toBe('array'); - expectToBeForScope(scope['implicit'].leftToBeResolved[1].from); + expect(scope.implicit.leftToBeResolved).toHaveLength(2); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('d'); + expectToBeForScope(scope.implicit.leftToBeResolved[0].from); + expect(scope.implicit.leftToBeResolved[1].identifier.name).toBe('array'); + expectToBeForScope(scope.implicit.leftToBeResolved[1].from); scope = scopeManager.scopes[2]; variables = getRealVariables(scope.variables); @@ -210,10 +210,10 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(3); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('d'); - expect(scope['implicit'].leftToBeResolved[1].identifier.name).toBe('e'); - expect(scope['implicit'].leftToBeResolved[2].identifier.name).toBe('array'); + expect(scope.implicit.leftToBeResolved).toHaveLength(3); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('d'); + expect(scope.implicit.leftToBeResolved[1].identifier.name).toBe('e'); + expect(scope.implicit.leftToBeResolved[2].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -277,13 +277,13 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(3); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('d'); - expectToBeForScope(scope['implicit'].leftToBeResolved[0].from); - expect(scope['implicit'].leftToBeResolved[1].identifier.name).toBe('e'); - expectToBeForScope(scope['implicit'].leftToBeResolved[1].from); - expect(scope['implicit'].leftToBeResolved[2].identifier.name).toBe('array'); - expectToBeForScope(scope['implicit'].leftToBeResolved[2].from); + expect(scope.implicit.leftToBeResolved).toHaveLength(3); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('d'); + expectToBeForScope(scope.implicit.leftToBeResolved[0].from); + expect(scope.implicit.leftToBeResolved[1].identifier.name).toBe('e'); + expectToBeForScope(scope.implicit.leftToBeResolved[1].from); + expect(scope.implicit.leftToBeResolved[2].identifier.name).toBe('array'); + expectToBeForScope(scope.implicit.leftToBeResolved[2].from); scope = scopeManager.scopes[2]; variables = getRealVariables(scope.variables); @@ -348,9 +348,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(2); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('d'); - expect(scope['implicit'].leftToBeResolved[1].identifier.name).toBe('array'); + expect(scope.implicit.leftToBeResolved).toHaveLength(2); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('d'); + expect(scope.implicit.leftToBeResolved[1].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -399,9 +399,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(2); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('d'); - expect(scope['implicit'].leftToBeResolved[1].identifier.name).toBe('array'); + expect(scope.implicit.leftToBeResolved).toHaveLength(2); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('d'); + expect(scope.implicit.leftToBeResolved[1].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -445,8 +445,8 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(1); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('array'); + expect(scope.implicit.leftToBeResolved).toHaveLength(1); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -485,8 +485,8 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(1); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('array'); + expect(scope.implicit.leftToBeResolved).toHaveLength(1); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -522,8 +522,8 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(1); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('array'); + expect(scope.implicit.leftToBeResolved).toHaveLength(1); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -570,10 +570,8 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(1); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe( - 'object', - ); + expect(scope.implicit.leftToBeResolved).toHaveLength(1); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('object'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -618,10 +616,8 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(1); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe( - 'object', - ); + expect(scope.implicit.leftToBeResolved).toHaveLength(1); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('object'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -677,9 +673,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(4); + expect(scope.implicit.leftToBeResolved).toHaveLength(4); expect( - scope['implicit'].leftToBeResolved.map(left => left.identifier.name), + scope.implicit.leftToBeResolved.map(left => left.identifier.name), ).toEqual(['a', 'b', 'c', 'array']); scope = scopeManager.scopes[1]; @@ -717,8 +713,8 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(1); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('array'); + expect(scope.implicit.leftToBeResolved).toHaveLength(1); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -759,9 +755,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(4); + expect(scope.implicit.leftToBeResolved).toHaveLength(4); expect( - scope['implicit'].leftToBeResolved.map(left => left.identifier.name), + scope.implicit.leftToBeResolved.map(left => left.identifier.name), ).toEqual(['a', 'b', 'rest', 'array']); scope = scopeManager.scopes[1]; @@ -795,9 +791,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(6); + expect(scope.implicit.leftToBeResolved).toHaveLength(6); expect( - scope['implicit'].leftToBeResolved.map(left => left.identifier.name), + scope.implicit.leftToBeResolved.map(left => left.identifier.name), ).toEqual(['a', 'b', 'c', 'd', 'rest', 'array']); scope = scopeManager.scopes[1]; @@ -836,9 +832,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(4); + expect(scope.implicit.leftToBeResolved).toHaveLength(4); expect( - scope['implicit'].leftToBeResolved.map(left => left.identifier.name), + scope.implicit.leftToBeResolved.map(left => left.identifier.name), ).toEqual(['a', 'b', 'obj', 'array']); scope = scopeManager.scopes[1]; @@ -880,9 +876,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(4); + expect(scope.implicit.leftToBeResolved).toHaveLength(4); expect( - scope['implicit'].leftToBeResolved.map(left => left.identifier.name), + scope.implicit.leftToBeResolved.map(left => left.identifier.name), ).toEqual(['shorthand', 'value', 'world', 'object']); scope = scopeManager.scopes[1]; @@ -925,9 +921,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope['implicit'].leftToBeResolved).toHaveLength(8); + expect(scope.implicit.leftToBeResolved).toHaveLength(8); expect( - scope['implicit'].leftToBeResolved.map(left => left.identifier.name), + scope.implicit.leftToBeResolved.map(left => left.identifier.name), ).toEqual(['shorthand', 'a', 'b', 'c', 'd', 'e', 'world', 'object']); scope = scopeManager.scopes[1]; @@ -971,8 +967,8 @@ describe('ES6 destructuring assignments', () => { expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(1); expect(scope.references[0].identifier.name).toBe('array'); - expect(scope['implicit'].leftToBeResolved).toHaveLength(1); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('array'); + expect(scope.implicit.leftToBeResolved).toHaveLength(1); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -1000,8 +996,8 @@ describe('ES6 destructuring assignments', () => { expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(1); expect(scope.references[0].identifier.name).toBe('array'); - expect(scope['implicit'].leftToBeResolved).toHaveLength(1); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('array'); + expect(scope.implicit.leftToBeResolved).toHaveLength(1); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -1039,10 +1035,8 @@ describe('ES6 destructuring assignments', () => { expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(1); expect(scope.references[0].identifier.name).toBe('object'); - expect(scope['implicit'].leftToBeResolved).toHaveLength(1); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe( - 'object', - ); + expect(scope.implicit.leftToBeResolved).toHaveLength(1); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('object'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -1075,10 +1069,8 @@ describe('ES6 destructuring assignments', () => { expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(1); expect(scope.references[0].identifier.name).toBe('object'); - expect(scope['implicit'].leftToBeResolved).toHaveLength(1); - expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe( - 'object', - ); + expect(scope.implicit.leftToBeResolved).toHaveLength(1); + expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('object'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); diff --git a/packages/scope-manager/tests/eslint-scope/implicit-global-reference.test.ts b/packages/scope-manager/tests/eslint-scope/implicit-global-reference.test.ts index 743d19873ec4..a8aa5ea7b4fb 100644 --- a/packages/scope-manager/tests/eslint-scope/implicit-global-reference.test.ts +++ b/packages/scope-manager/tests/eslint-scope/implicit-global-reference.test.ts @@ -23,9 +23,9 @@ describe('implicit global reference', () => { ).toEqual([[[DefinitionType.Variable]]]); expectToBeGlobalScope(scopes[0]); - expect( - scopes[0]['implicit'].variables.map(variable => variable.name), - ).toEqual([]); + expect(scopes[0].implicit.variables.map(variable => variable.name)).toEqual( + [], + ); }); it('assignments global scope without definition', () => { @@ -45,9 +45,9 @@ describe('implicit global reference', () => { ).toEqual([[]]); expectToBeGlobalScope(scopes[0]); - expect( - scopes[0]['implicit'].variables.map(variable => variable.name), - ).toEqual(['x']); + expect(scopes[0].implicit.variables.map(variable => variable.name)).toEqual( + ['x'], + ); }); it('assignments global scope without definition eval', () => { @@ -69,9 +69,9 @@ describe('implicit global reference', () => { ).toEqual([[[DefinitionType.FunctionName]], [[]]]); expectToBeGlobalScope(scopes[0]); - expect( - scopes[0]['implicit'].variables.map(variable => variable.name), - ).toEqual(['x']); + expect(scopes[0].implicit.variables.map(variable => variable.name)).toEqual( + ['x'], + ); }); it('assignment leaks', () => { @@ -90,9 +90,9 @@ describe('implicit global reference', () => { ).toEqual([['outer'], ['arguments']]); expectToBeGlobalScope(scopes[0]); - expect( - scopes[0]['implicit'].variables.map(variable => variable.name), - ).toEqual(['x']); + expect(scopes[0].implicit.variables.map(variable => variable.name)).toEqual( + ['x'], + ); }); it("assignment doesn't leak", () => { @@ -114,9 +114,9 @@ describe('implicit global reference', () => { ).toEqual([['outer'], ['arguments', 'inner', 'x'], ['arguments']]); expectToBeGlobalScope(scopes[0]); - expect( - scopes[0]['implicit'].variables.map(variable => variable.name), - ).toEqual([]); + expect(scopes[0].implicit.variables.map(variable => variable.name)).toEqual( + [], + ); }); it('for-in-statement leaks', () => { @@ -135,9 +135,9 @@ describe('implicit global reference', () => { ).toEqual([['outer'], ['arguments'], []]); expectToBeGlobalScope(scopes[0]); - expect( - scopes[0]['implicit'].variables.map(variable => variable.name), - ).toEqual(['x']); + expect(scopes[0].implicit.variables.map(variable => variable.name)).toEqual( + ['x'], + ); }); it("for-in-statement doesn't leaks", () => { @@ -159,8 +159,8 @@ describe('implicit global reference', () => { ).toEqual([['outer'], ['arguments', 'inner', 'x'], ['arguments'], []]); expectToBeGlobalScope(scopes[0]); - expect( - scopes[0]['implicit'].variables.map(variable => variable.name), - ).toEqual([]); + expect(scopes[0].implicit.variables.map(variable => variable.name)).toEqual( + [], + ); }); }); diff --git a/packages/scope-manager/tests/eslint-scope/references.test.ts b/packages/scope-manager/tests/eslint-scope/references.test.ts index 0b49cab0f7f5..22fed597c3e7 100644 --- a/packages/scope-manager/tests/eslint-scope/references.test.ts +++ b/packages/scope-manager/tests/eslint-scope/references.test.ts @@ -447,7 +447,7 @@ describe('References:', () => { 'new function({b: a = 0} = {}) {}', ]; - trueCodes.forEach(code => + trueCodes.forEach(code => { it(`"${code}", all references should be true.`, () => { const { scopeManager } = parseAndAnalyze(code); @@ -464,8 +464,8 @@ describe('References:', () => { expect(reference.isWrite()).toBeTruthy(); expect(reference.init).toBeTruthy(); }); - }), - ); + }); + }); let falseCodes = [ 'let a; a = 0;', @@ -481,7 +481,7 @@ describe('References:', () => { 'let a; for ({a = 0} in []);', ]; - falseCodes.forEach(code => + falseCodes.forEach(code => { it(`"${code}", all references should be false.`, () => { const { scopeManager } = parseAndAnalyze(code); @@ -498,8 +498,8 @@ describe('References:', () => { expect(reference.isWrite()).toBeTruthy(); expect(reference.init).toBeFalsy(); }); - }), - ); + }); + }); falseCodes = [ 'let a; let b = a;', @@ -517,7 +517,7 @@ describe('References:', () => { 'let a; a.foo = 0;', 'let a,b; b = a.foo;', ]; - falseCodes.forEach(code => + falseCodes.forEach(code => { it(`"${code}", readonly references of "a" should be undefined.`, () => { const { scopeManager } = parseAndAnalyze(code); @@ -537,8 +537,8 @@ describe('References:', () => { expect(reference.isRead()).toBeTruthy(); expect(reference.init).toBeUndefined(); }); - }), - ); + }); + }); }); describe('When emitDecoratorMetadata is true', () => { diff --git a/packages/scope-manager/tests/fixtures.test.ts b/packages/scope-manager/tests/fixtures.test.ts index 9f628bfe41e8..85cc8a3cd7e2 100644 --- a/packages/scope-manager/tests/fixtures.test.ts +++ b/packages/scope-manager/tests/fixtures.test.ts @@ -172,7 +172,9 @@ function nestDescribe( } } -fixtures.forEach(f => nestDescribe(f)); +fixtures.forEach(f => { + nestDescribe(f); +}); if (ONLY === '') { // ensure that the snapshots are cleaned up, because jest-specific-snapshot won't do this check diff --git a/packages/type-utils/tests/isTypeReadonly.test.ts b/packages/type-utils/tests/isTypeReadonly.test.ts index 2adfaaec7aa8..c88970dc8975 100644 --- a/packages/type-utils/tests/isTypeReadonly.test.ts +++ b/packages/type-utils/tests/isTypeReadonly.test.ts @@ -139,13 +139,15 @@ describe('isTypeReadonly', () => { describe('is readonly circular', () => { const runTests = runTestIsReadonly; - it('handles circular readonly PropertySignature inside a readonly IndexSignature', () => - runTests('interface Test { readonly [key: string]: Test };')); + it('handles circular readonly PropertySignature inside a readonly IndexSignature', () => { + runTests('interface Test { readonly [key: string]: Test };'); + }); - it('handles circular readonly PropertySignature inside interdependent objects', () => + it('handles circular readonly PropertySignature inside interdependent objects', () => { runTests( 'interface Test1 { readonly [key: string]: Test } interface Test { readonly [key: string]: Test1 }', - )); + ); + }); }); describe('is not readonly', () => { @@ -163,8 +165,9 @@ describe('isTypeReadonly', () => { describe('is not readonly circular', () => { const runTests = runTestIsNotReadonly; - it('handles circular mutable PropertySignature', () => - runTests('interface Test { [key: string]: Test };')); + it('handles circular mutable PropertySignature', () => { + runTests('interface Test { [key: string]: Test };'); + }); it.each([ [ diff --git a/packages/types/tools/copy-ast-spec.ts b/packages/types/tools/copy-ast-spec.ts index dc2227ae48bc..f0499a91a4fb 100644 --- a/packages/types/tools/copy-ast-spec.ts +++ b/packages/types/tools/copy-ast-spec.ts @@ -19,9 +19,15 @@ async function execAsync( stdio: 'inherit', }); - child.on('error', e => reject(e)); - child.on('exit', () => resolve()); - child.on('close', () => resolve()); + child.on('error', e => { + reject(e); + }); + child.on('exit', () => { + resolve(); + }); + child.on('close', () => { + resolve(); + }); }); } diff --git a/packages/typescript-estree/src/create-program/createDefaultProgram.ts b/packages/typescript-estree/src/create-program/createDefaultProgram.ts index 9ad68838e55a..76db0b406f89 100644 --- a/packages/typescript-estree/src/create-program/createDefaultProgram.ts +++ b/packages/typescript-estree/src/create-program/createDefaultProgram.ts @@ -32,7 +32,12 @@ function createDefaultProgram( const commandLine = ts.getParsedCommandLineOfConfigFile( tsconfigPath, createDefaultCompilerOptionsFromExtra(parseSettings), - { ...ts.sys, onUnRecoverableConfigFileDiagnostic: () => {} }, + { + ...ts.sys, + // TODO: file issue on TypeScript to suggest making optional? + // eslint-disable-next-line @typescript-eslint/no-empty-function + onUnRecoverableConfigFileDiagnostic: () => {}, + }, ); if (!commandLine) { diff --git a/packages/typescript-estree/src/create-program/createProjectProgram.ts b/packages/typescript-estree/src/create-program/createProjectProgram.ts index 51a2ebdfdfc6..9996bdf9ba6f 100644 --- a/packages/typescript-estree/src/create-program/createProjectProgram.ts +++ b/packages/typescript-estree/src/create-program/createProjectProgram.ts @@ -38,7 +38,7 @@ function createProjectProgram( // The file was either matched within the tsconfig, or we allow creating a default program // eslint-disable-next-line deprecation/deprecation -- will be cleaned up with the next major - if (astAndProgram || parseSettings.DEPRECATED__createDefaultProgram) { + if (astAndProgram ?? parseSettings.DEPRECATED__createDefaultProgram) { return astAndProgram; } diff --git a/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts b/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts index 01ab04c3ae56..cd33a9a4aa24 100644 --- a/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts +++ b/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts @@ -146,9 +146,9 @@ function getWatchProgramsForProjects( fileWatchCallbacks && fileWatchCallbacks.size > 0 ) { - fileWatchCallbacks.forEach(cb => - cb(filePath, ts.FileWatcherEventKind.Changed), - ); + fileWatchCallbacks.forEach(cb => { + cb(filePath, ts.FileWatcherEventKind.Changed); + }); } const currentProjectsFromSettings = new Set(parseSettings.projects); @@ -264,6 +264,8 @@ function createWatchProgram( ts.sys, ts.createAbstractBuilder, diagnosticReporter, + // TODO: file issue on TypeScript to suggest making optional? + // eslint-disable-next-line @typescript-eslint/no-empty-function /*reportWatchStatus*/ () => {}, ) as WatchCompilerHostOfConfigFile; @@ -398,9 +400,9 @@ function maybeInvalidateProgram( * We need to make sure typescript knows this so it can update appropriately */ log('tsconfig has changed - triggering program update. %s', tsconfigPath); - fileWatchCallbackTrackingMap - .get(tsconfigPath)! - .forEach(cb => cb(tsconfigPath, ts.FileWatcherEventKind.Changed)); + fileWatchCallbackTrackingMap.get(tsconfigPath)!.forEach(cb => { + cb(tsconfigPath, ts.FileWatcherEventKind.Changed); + }); // tsconfig change means that the file list more than likely changed, so clear the cache programFileListCache.delete(tsconfigPath); @@ -485,9 +487,9 @@ function maybeInvalidateProgram( } log('Marking file as deleted. %s', deletedFile); - fileWatchCallbacks.forEach(cb => - cb(deletedFile, ts.FileWatcherEventKind.Deleted), - ); + fileWatchCallbacks.forEach(cb => { + cb(deletedFile, ts.FileWatcherEventKind.Deleted); + }); // deleted files means that the file list _has_ changed, so clear the cache programFileListCache.delete(tsconfigPath); diff --git a/packages/typescript-estree/src/create-program/useProvidedPrograms.ts b/packages/typescript-estree/src/create-program/useProvidedPrograms.ts index 96093e9a3afa..3eca9eefa5b2 100644 --- a/packages/typescript-estree/src/create-program/useProvidedPrograms.ts +++ b/packages/typescript-estree/src/create-program/useProvidedPrograms.ts @@ -70,7 +70,7 @@ function createProgramFromConfigFile( }, fileExists: fs.existsSync, getCurrentDirectory: () => - (projectDirectory && path.resolve(projectDirectory)) || process.cwd(), + (projectDirectory && path.resolve(projectDirectory)) ?? process.cwd(), readDirectory: ts.sys.readDirectory, readFile: file => fs.readFileSync(file, 'utf-8'), useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames, diff --git a/packages/typescript-estree/src/node-utils.ts b/packages/typescript-estree/src/node-utils.ts index 74e53c5df21e..551a308420cd 100644 --- a/packages/typescript-estree/src/node-utils.ts +++ b/packages/typescript-estree/src/node-utils.ts @@ -363,7 +363,7 @@ export function hasJSXAncestor(node: ts.Node): boolean { export function unescapeStringLiteralText(text: string): string { return text.replace(/&(?:#\d+|#x[\da-fA-F]+|[0-9a-zA-Z]+);/g, entity => { const item = entity.slice(1, -1); - if (item[0] === '#') { + if (item.startsWith('#')) { const codePoint = item[1] === 'x' ? parseInt(item.slice(2), 16) diff --git a/packages/typescript-estree/src/parseSettings/createParseSettings.ts b/packages/typescript-estree/src/parseSettings/createParseSettings.ts index dbf36c2df90f..b26e00376977 100644 --- a/packages/typescript-estree/src/parseSettings/createParseSettings.ts +++ b/packages/typescript-estree/src/parseSettings/createParseSettings.ts @@ -66,7 +66,7 @@ export function createParseSettings( typeof options.loggerFn === 'function' ? options.loggerFn : options.loggerFn === false - ? (): void => {} + ? (): void => {} // eslint-disable-line @typescript-eslint/no-empty-function : console.log, // eslint-disable-line no-console preserveNodeMaps: options.preserveNodeMaps !== false, programs: Array.isArray(options.programs) ? options.programs : null, diff --git a/packages/typescript-estree/src/parser.ts b/packages/typescript-estree/src/parser.ts index c74935498c14..833023e75d69 100644 --- a/packages/typescript-estree/src/parser.ts +++ b/packages/typescript-estree/src/parser.ts @@ -80,6 +80,7 @@ function getProgramAndAST( return createNoProgram(parseSettings); } +// eslint-disable-next-line @typescript-eslint/no-empty-interface interface EmptyObject {} type AST = TSESTree.Program & (T['comment'] extends true ? { comments: TSESTree.Comment[] } : EmptyObject) & @@ -142,7 +143,7 @@ function parseWithNodeMapsInternal( }; } -let parseAndGenerateServicesCalls: { [fileName: string]: number } = {}; +let parseAndGenerateServicesCalls: Record = {}; // Privately exported utility intended for use in typescript-eslint unit tests only function clearParseAndGenerateServicesCalls(): void { parseAndGenerateServicesCalls = {}; diff --git a/packages/typescript-estree/src/simple-traverse.ts b/packages/typescript-estree/src/simple-traverse.ts index 67b56d02c380..5590bff21920 100644 --- a/packages/typescript-estree/src/simple-traverse.ts +++ b/packages/typescript-estree/src/simple-traverse.ts @@ -24,12 +24,10 @@ type SimpleTraverseOptions = Readonly< } | { visitorKeys?: Readonly; - visitors: { - [key: string]: ( - node: TSESTree.Node, - parent: TSESTree.Node | undefined, - ) => void; - }; + visitors: Record< + string, + (node: TSESTree.Node, parent: TSESTree.Node | undefined) => void + >; } >; diff --git a/packages/typescript-estree/src/ts-estree/ts-nodes.ts b/packages/typescript-estree/src/ts-estree/ts-nodes.ts index 570ae9e80a7a..27d89b0f4f66 100644 --- a/packages/typescript-estree/src/ts-estree/ts-nodes.ts +++ b/packages/typescript-estree/src/ts-estree/ts-nodes.ts @@ -2,6 +2,7 @@ import type * as ts from 'typescript'; // Workaround to support new TS version features for consumers on old TS versions // Eg: https://github.com/typescript-eslint/typescript-eslint/issues/2388, https://github.com/typescript-eslint/typescript-eslint/issues/2784 +/* eslint-disable @typescript-eslint/no-empty-interface */ declare module 'typescript' { // added in TS 4.0 export interface NamedTupleMember extends ts.Node {} @@ -16,6 +17,7 @@ declare module 'typescript' { // added in TS 4.9 export interface SatisfiesExpression extends ts.Node {} } +/* eslint-enable @typescript-eslint/no-empty-interface */ export type TSToken = ts.Token; diff --git a/packages/typescript-estree/tests/lib/convert.test.ts b/packages/typescript-estree/tests/lib/convert.test.ts index b9ec249d67bf..97b22624acac 100644 --- a/packages/typescript-estree/tests/lib/convert.test.ts +++ b/packages/typescript-estree/tests/lib/convert.test.ts @@ -21,73 +21,77 @@ describe('convert', () => { ); } - it('deeplyCopy should convert node correctly', () => { - const ast = convertCode('type foo = ?foo | ?(() => void)?'); + /* eslint-disable @typescript-eslint/dot-notation */ + describe('deeplyCopy', () => { + it('deeplyCopy should convert node correctly', () => { + const ast = convertCode('type foo = ?foo | ?(() => void)?'); - function fakeUnknownKind(node: ts.Node): void { - ts.forEachChild(node, fakeUnknownKind); - // @ts-expect-error -- intentionally writing to a readonly field - // eslint-disable-next-line deprecation/deprecation - node.kind = ts.SyntaxKind.UnparsedPrologue; - } + function fakeUnknownKind(node: ts.Node): void { + ts.forEachChild(node, fakeUnknownKind); + // @ts-expect-error -- intentionally writing to a readonly field + // eslint-disable-next-line deprecation/deprecation + node.kind = ts.SyntaxKind.UnparsedPrologue; + } - ts.forEachChild(ast, fakeUnknownKind); + ts.forEachChild(ast, fakeUnknownKind); - const instance = new Converter(ast); - expect(instance.convertProgram()).toMatchSnapshot(); - }); + const instance = new Converter(ast); + expect(instance.convertProgram()).toMatchSnapshot(); + }); - it('deeplyCopy should convert node with decorators correctly', () => { - const ast = convertCode('@test class foo {}'); + it('deeplyCopy should convert node with decorators correctly', () => { + const ast = convertCode('@test class foo {}'); - const instance = new Converter(ast); + const instance = new Converter(ast); - expect( - instance['deeplyCopy'](ast.statements[0] as ts.ClassDeclaration), - ).toMatchSnapshot(); - }); + expect( + instance['deeplyCopy'](ast.statements[0] as ts.ClassDeclaration), + ).toMatchSnapshot(); + }); - it('deeplyCopy should convert node with type parameters correctly', () => { - const ast = convertCode('class foo {}'); + it('deeplyCopy should convert node with type parameters correctly', () => { + const ast = convertCode('class foo {}'); - const instance = new Converter(ast); + const instance = new Converter(ast); - expect( - instance['deeplyCopy'](ast.statements[0] as ts.ClassDeclaration), - ).toMatchSnapshot(); - }); + expect( + instance['deeplyCopy'](ast.statements[0] as ts.ClassDeclaration), + ).toMatchSnapshot(); + }); - it('deeplyCopy should convert node with type arguments correctly', () => { - const ast = convertCode('new foo()'); + it('deeplyCopy should convert node with type arguments correctly', () => { + const ast = convertCode('new foo()'); - const instance = new Converter(ast); + const instance = new Converter(ast); - expect( - instance['deeplyCopy']( - (ast.statements[0] as ts.ExpressionStatement) - .expression as ts.NewExpression, - ), - ).toMatchSnapshot(); - }); + expect( + instance['deeplyCopy']( + (ast.statements[0] as ts.ExpressionStatement) + .expression as ts.NewExpression, + ), + ).toMatchSnapshot(); + }); - it('deeplyCopy should convert array of nodes', () => { - const ast = convertCode('new foo()'); + it('deeplyCopy should convert array of nodes', () => { + const ast = convertCode('new foo()'); - const instance = new Converter(ast); - expect(instance['deeplyCopy'](ast)).toMatchSnapshot(); - }); + const instance = new Converter(ast); + expect(instance['deeplyCopy'](ast)).toMatchSnapshot(); + }); - it('deeplyCopy should fail on unknown node', () => { - const ast = convertCode('type foo = ?foo | ?(() => void)?'); + it('deeplyCopy should fail on unknown node', () => { + const ast = convertCode('type foo = ?foo | ?(() => void)?'); - const instance = new Converter(ast, { - errorOnUnknownASTType: true, - }); + const instance = new Converter(ast, { + errorOnUnknownASTType: true, + }); - expect(() => instance['deeplyCopy'](ast)).toThrow( - 'Unknown AST_NODE_TYPE: "TSSourceFile"', - ); + expect(() => instance['deeplyCopy'](ast)).toThrow( + 'Unknown AST_NODE_TYPE: "TSSourceFile"', + ); + }); }); + /* eslint-enable @typescript-eslint/dot-notation */ it('nodeMaps should contain basic nodes', () => { const ast = convertCode(` @@ -188,46 +192,50 @@ describe('convert', () => { checkMaps(ast); }); - it('should correctly create node with range and loc set', () => { - const ast = convertCode(''); - const instance = new Converter(ast, { - shouldPreserveNodeMaps: true, - }); + /* eslint-disable @typescript-eslint/dot-notation */ + describe('createNode', () => { + it('should correctly create node with range and loc set', () => { + const ast = convertCode(''); + const instance = new Converter(ast, { + shouldPreserveNodeMaps: true, + }); - const tsNode: ts.KeywordToken = { - ...ts.factory.createToken(ts.SyntaxKind.AbstractKeyword), - end: 10, - pos: 0, - }; - const convertedNode = instance['createNode'](tsNode, { - type: AST_NODE_TYPES.TSAbstractKeyword, - range: [0, 20], - loc: { - start: { - line: 10, - column: 20, - }, - end: { - line: 15, - column: 25, + const tsNode: ts.KeywordToken = { + ...ts.factory.createToken(ts.SyntaxKind.AbstractKeyword), + end: 10, + pos: 0, + }; + const convertedNode = instance['createNode'](tsNode, { + type: AST_NODE_TYPES.TSAbstractKeyword, + range: [0, 20], + loc: { + start: { + line: 10, + column: 20, + }, + end: { + line: 15, + column: 25, + }, }, - }, - }); - expect(convertedNode).toEqual({ - type: AST_NODE_TYPES.TSAbstractKeyword, - range: [0, 20], - loc: { - start: { - line: 10, - column: 20, - }, - end: { - line: 15, - column: 25, + }); + expect(convertedNode).toEqual({ + type: AST_NODE_TYPES.TSAbstractKeyword, + range: [0, 20], + loc: { + start: { + line: 10, + column: 20, + }, + end: { + line: 15, + column: 25, + }, }, - }, + }); }); }); + /* eslint-enable @typescript-eslint/dot-notation */ it('should throw error on jsDoc node', () => { const jsDocCode = [ diff --git a/packages/typescript-estree/tests/lib/persistentParse.test.ts b/packages/typescript-estree/tests/lib/persistentParse.test.ts index 63e81d7e260a..30bf442af399 100644 --- a/packages/typescript-estree/tests/lib/persistentParse.test.ts +++ b/packages/typescript-estree/tests/lib/persistentParse.test.ts @@ -22,7 +22,9 @@ afterEach(() => { clearWatchCaches(); // clean up the temporary files and folders - tmpDirs.forEach(t => t.removeCallback()); + tmpDirs.forEach(t => { + t.removeCallback(); + }); tmpDirs.clear(); // restore original cwd @@ -89,31 +91,47 @@ function baseTests( it('parses both files successfully when included', () => { const PROJECT_DIR = setup(tsConfigIncludeAll); - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR); + }).not.toThrow(); }); it('parses included files, and throws on excluded files', () => { const PROJECT_DIR = setup(tsConfigExcludeBar); - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR)).toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR); + }).toThrow(); }); it('allows parsing of new files', () => { const PROJECT_DIR = setup(tsConfigIncludeAll, false); // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); // bar should throw because it doesn't exist yet - expect(() => parseFile('bar', PROJECT_DIR)).toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR); + }).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, 'bar'); // both files should parse fine now - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR); + }).not.toThrow(); }); it('allows parsing of deeply nested new files', () => { @@ -121,22 +139,32 @@ function baseTests( const bazSlashBar = 'baz/bar' as const; // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); // bar should throw because it doesn't exist yet - expect(() => parseFile(bazSlashBar, PROJECT_DIR)).toThrow(); + expect(() => { + parseFile(bazSlashBar, PROJECT_DIR); + }).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, bazSlashBar); // both files should parse fine now - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile(bazSlashBar, PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile(bazSlashBar, PROJECT_DIR); + }).not.toThrow(); }); it('allows parsing of deeply nested new files in new folder', () => { const PROJECT_DIR = setup(tsConfigIncludeAll); - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); // Create deep folder structure after first parse (this is important step) // context: https://github.com/typescript-eslint/typescript-eslint/issues/1394 @@ -148,7 +176,9 @@ function baseTests( // write a new file and attempt to parse it writeFile(PROJECT_DIR, bazSlashBar); - expect(() => parseFile(bazSlashBar, PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile(bazSlashBar, PROJECT_DIR); + }).not.toThrow(); }); it('allows renaming of files', () => { @@ -156,39 +186,59 @@ function baseTests( const bazSlashBar = 'baz/bar' as const; // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); // bar should throw because it doesn't exist yet - expect(() => parseFile(bazSlashBar, PROJECT_DIR)).toThrow(); + expect(() => { + parseFile(bazSlashBar, PROJECT_DIR); + }).toThrow(); // write a new file and attempt to parse it renameFile(PROJECT_DIR, 'bar', bazSlashBar); // both files should parse fine now - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile(bazSlashBar, PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile(bazSlashBar, PROJECT_DIR); + }).not.toThrow(); }); it('reacts to changes in the tsconfig', () => { const PROJECT_DIR = setup(tsConfigExcludeBar); // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR)).toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR); + }).toThrow(); // change the config file so it now includes all files writeTSConfig(PROJECT_DIR, tsConfigIncludeAll); - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR); + }).not.toThrow(); }); it('should work with relative paths', () => { const PROJECT_DIR = setup(tsConfigIncludeAll, false); // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => parseFile('foo', PROJECT_DIR, true)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR, true); + }).not.toThrow(); // bar should throw because it doesn't exist yet - expect(() => parseFile('bar', PROJECT_DIR, true)).toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR, true); + }).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, 'bar'); @@ -197,8 +247,12 @@ function baseTests( expect(existsSync('bar', PROJECT_DIR)).toBe(true); // both files should parse fine now - expect(() => parseFile('foo', PROJECT_DIR, true)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR, true)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR, true); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR, true); + }).not.toThrow(); }); it('should work with relative paths without tsconfig root', () => { @@ -206,9 +260,13 @@ function baseTests( process.chdir(PROJECT_DIR); // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => parseFile('foo', PROJECT_DIR, true, true)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR, true, true); + }).not.toThrow(); // bar should throw because it doesn't exist yet - expect(() => parseFile('bar', PROJECT_DIR, true, true)).toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR, true, true); + }).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, 'bar'); @@ -218,8 +276,12 @@ function baseTests( expect(existsSync('bar', PROJECT_DIR)).toBe(true); // both files should parse fine now - expect(() => parseFile('foo', PROJECT_DIR, true, true)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR, true, true)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR, true, true); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR, true, true); + }).not.toThrow(); }); } @@ -269,14 +331,22 @@ describe('persistent parse', () => { const PROJECT_DIR = setup({}, false); // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR)).toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR); + }).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, 'bar'); - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR); + }).not.toThrow(); }); it('handles tsconfigs with no includes/excludes (nested)', () => { @@ -284,14 +354,22 @@ describe('persistent parse', () => { const bazSlashBar = 'baz/bar' as const; // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile(bazSlashBar, PROJECT_DIR)).toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile(bazSlashBar, PROJECT_DIR); + }).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, bazSlashBar); - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile(bazSlashBar, PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile(bazSlashBar, PROJECT_DIR); + }).not.toThrow(); }); }); @@ -334,7 +412,9 @@ describe('persistent parse', () => { it(`first parse of ${name} should not throw`, () => { const PROJECT_DIR = setup(tsConfigIncludeAll); writeFile(PROJECT_DIR, name); - expect(() => parseFile(name, PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile(name, PROJECT_DIR); + }).not.toThrow(); }); } }); diff --git a/packages/typescript-estree/tests/lib/semanticInfo.test.ts b/packages/typescript-estree/tests/lib/semanticInfo.test.ts index 6c50712e0eae..8dc9cfda9ecd 100644 --- a/packages/typescript-estree/tests/lib/semanticInfo.test.ts +++ b/packages/typescript-estree/tests/lib/semanticInfo.test.ts @@ -37,7 +37,9 @@ function createOptions(fileName: string): TSESTreeOptions & { cwd?: string } { } // ensure tsconfig-parser watch caches are clean for each test -beforeEach(() => clearWatchCaches()); +beforeEach(() => { + clearWatchCaches(); +}); describe('semanticInfo', () => { // test all AST snapshots diff --git a/packages/utils/src/ast-utils/eslint-utils/PatternMatcher.ts b/packages/utils/src/ast-utils/eslint-utils/PatternMatcher.ts index 0cf5708f82ed..639677087bf4 100644 --- a/packages/utils/src/ast-utils/eslint-utils/PatternMatcher.ts +++ b/packages/utils/src/ast-utils/eslint-utils/PatternMatcher.ts @@ -49,8 +49,9 @@ interface PatternMatcher { * * @see {@link https://eslint-community.github.io/eslint-utils/api/ast-utils.html#patternmatcher-class} */ -const PatternMatcher = eslintUtils.PatternMatcher as { - new (pattern: RegExp, options?: { escaped?: boolean }): PatternMatcher; -}; +const PatternMatcher = eslintUtils.PatternMatcher as new ( + pattern: RegExp, + options?: { escaped?: boolean }, +) => PatternMatcher; export { PatternMatcher }; diff --git a/packages/utils/src/json-schema.ts b/packages/utils/src/json-schema.ts index b641637745ae..4a09a589ad20 100644 --- a/packages/utils/src/json-schema.ts +++ b/packages/utils/src/json-schema.ts @@ -106,19 +106,11 @@ interface JSONSchema4Base { /** * Reusable definitions that can be referenced via `$ref` */ - definitions?: - | { - [k: string]: JSONSchema4; - } - | undefined; + definitions?: Record | undefined; /** * Reusable definitions that can be referenced via `$ref` */ - $defs?: - | { - [k: string]: JSONSchema4; - } - | undefined; + $defs?: Record | undefined; /** * The value of this property MUST be another schema which will provide @@ -242,11 +234,7 @@ export interface JSONSchema4ObjectSchema extends JSONSchema4Base { * * @see https://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.2 */ - properties?: - | { - [k: string]: JSONSchema4; - } - | undefined; + properties?: Record | undefined; /** * This attribute is an object that defines the schema for a set of @@ -259,22 +247,14 @@ export interface JSONSchema4ObjectSchema extends JSONSchema4Base { * * @see https://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.3 */ - patternProperties?: - | { - [k: string]: JSONSchema4; - } - | undefined; + patternProperties?: Record | undefined; /** * The `dependencies` keyword conditionally applies a sub-schema when a given * property is present. This schema is applied in the same way `allOf` applies * schemas. Nothing is merged or extended. Both schemas apply independently. */ - dependencies?: - | { - [k: string]: JSONSchema4 | string[]; - } - | undefined; + dependencies?: Record | undefined; /** * The maximum number of properties allowed for record-style schemas diff --git a/packages/utils/src/ts-eslint/CLIEngine.ts b/packages/utils/src/ts-eslint/CLIEngine.ts index 15a58754ec93..ccd785dc5f5c 100644 --- a/packages/utils/src/ts-eslint/CLIEngine.ts +++ b/packages/utils/src/ts-eslint/CLIEngine.ts @@ -106,7 +106,7 @@ declare class CLIEngineBase { namespace CLIEngine { export interface Options { allowInlineConfig?: boolean; - baseConfig?: false | { [name: string]: unknown }; + baseConfig?: Record | false; cache?: boolean; cacheFile?: string; cacheLocation?: string; @@ -125,9 +125,7 @@ namespace CLIEngine { parserOptions?: Linter.ParserOptions; plugins?: string[]; resolvePluginsRelativeTo?: string; - rules?: { - [name: string]: Linter.RuleLevel | Linter.RuleLevelAndOptions; - }; + rules?: Record; rulePaths?: string[]; reportUnusedDisableDirectives?: boolean; } @@ -158,9 +156,7 @@ namespace CLIEngine { } export interface LintResultData { - rulesMeta: { - [ruleId: string]: RuleMetaData; - }; + rulesMeta: Record>; } export type Formatter = ( diff --git a/packages/utils/src/ts-eslint/Linter.ts b/packages/utils/src/ts-eslint/Linter.ts index 59274a7e6fc4..62a6645e0091 100644 --- a/packages/utils/src/ts-eslint/Linter.ts +++ b/packages/utils/src/ts-eslint/Linter.ts @@ -130,12 +130,8 @@ namespace Linter { export type GlobalVariableOptionBase = 'off' | 'readonly' | 'writable'; export type GlobalVariableOption = GlobalVariableOptionBase | boolean; - export interface GlobalsConfig { - [name: string]: GlobalVariableOption; - } - export interface EnvironmentConfig { - [name: string]: boolean; - } + export type GlobalsConfig = Record; + export type EnvironmentConfig = Record; // https://github.com/eslint/eslint/blob/v6.8.0/conf/config-schema.js interface BaseConfig { diff --git a/packages/utils/src/ts-eslint/Rule.ts b/packages/utils/src/ts-eslint/Rule.ts index 16d34a67fc2a..87309acb568b 100644 --- a/packages/utils/src/ts-eslint/Rule.ts +++ b/packages/utils/src/ts-eslint/Rule.ts @@ -170,6 +170,7 @@ type ReportDescriptor = * Plugins can add their settings using declaration * merging against this interface. */ +// eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style interface SharedConfigurationSettings { [name: string]: unknown; } @@ -428,10 +429,9 @@ interface RuleListenerBaseSelectors { type RuleListenerExitSelectors = { [K in keyof RuleListenerBaseSelectors as `${K}:exit`]: RuleListenerBaseSelectors[K]; }; -interface RuleListenerCatchAllBaseCase { - [nodeSelector: string]: RuleFunction | undefined; -} +type RuleListenerCatchAllBaseCase = Record; // Interface to merge into for anyone that wants to add more selectors +// eslint-disable-next-line @typescript-eslint/no-empty-interface interface RuleListenerExtension {} type RuleListener = RuleListenerBaseSelectors & diff --git a/packages/utils/src/ts-eslint/SourceCode.ts b/packages/utils/src/ts-eslint/SourceCode.ts index 3d7f33dd93c2..7e8352b13d9d 100644 --- a/packages/utils/src/ts-eslint/SourceCode.ts +++ b/packages/utils/src/ts-eslint/SourceCode.ts @@ -384,9 +384,7 @@ namespace SourceCode { visitorKeys: VisitorKeys | null; } - export interface VisitorKeys { - [nodeType: string]: string[]; - } + export type VisitorKeys = Record; export type FilterPredicate = (token: TSESTree.Token) => boolean; export type GetFilterPredicate = diff --git a/packages/utils/tests/eslint-utils/nullThrows.test.ts b/packages/utils/tests/eslint-utils/nullThrows.test.ts index 7997fecaa6df..b213b3900bf5 100644 --- a/packages/utils/tests/eslint-utils/nullThrows.test.ts +++ b/packages/utils/tests/eslint-utils/nullThrows.test.ts @@ -24,8 +24,8 @@ describe('nullThrows', () => { }); it('throws an error when the value is undefined', () => { - expect(() => - nullThrows(undefined, NullThrowsReasons.MissingParent), - ).toThrow(NullThrowsReasons.MissingParent); + expect(() => { + nullThrows(undefined, NullThrowsReasons.MissingParent); + }).toThrow(NullThrowsReasons.MissingParent); }); }); diff --git a/packages/visitor-keys/src/visitor-keys.ts b/packages/visitor-keys/src/visitor-keys.ts index eaff7e7ccc26..f4d61fd6230d 100644 --- a/packages/visitor-keys/src/visitor-keys.ts +++ b/packages/visitor-keys/src/visitor-keys.ts @@ -1,9 +1,7 @@ import type { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/types'; import * as eslintVisitorKeys from 'eslint-visitor-keys'; -interface VisitorKeys { - readonly [type: string]: readonly string[] | undefined; -} +type VisitorKeys = Readonly>; type GetNodeTypeKeys = Exclude< keyof Extract, diff --git a/packages/website/src/components/OptionsSelector.tsx b/packages/website/src/components/OptionsSelector.tsx index 5ab5421be966..95f491c0112b 100644 --- a/packages/website/src/components/OptionsSelector.tsx +++ b/packages/website/src/components/OptionsSelector.tsx @@ -55,7 +55,9 @@ function OptionsSelectorContent({ className="text--right" value={state.ts} disabled={!tsVersions.length} - onChange={(ts): void => setState({ ts })} + onChange={(ts): void => { + setState({ ts }); + }} options={(tsVersions.length && tsVersions) || [state.ts]} /> @@ -67,7 +69,9 @@ function OptionsSelectorContent({ setState({ fileType })} + onChange={(fileType): void => { + setState({ fileType }); + }} options={fileTypes} /> @@ -75,7 +79,9 @@ function OptionsSelectorContent({ setState({ sourceType })} + onChange={(sourceType): void => { + setState({ sourceType }); + }} options={['script', 'module']} /> @@ -83,14 +89,18 @@ function OptionsSelectorContent({ setState({ scroll })} + onChange={(scroll): void => { + setState({ scroll }); + }} /> setState({ showTokens })} + onChange={(showTokens): void => { + setState({ showTokens }); + }} /> diff --git a/packages/website/src/components/Playground.tsx b/packages/website/src/components/Playground.tsx index d0e9be8a31c7..c443dc66277d 100644 --- a/packages/website/src/components/Playground.tsx +++ b/packages/website/src/components/Playground.tsx @@ -152,7 +152,9 @@ function Playground(): JSX.Element { setState({ showAST: v })} + change={(v): void => { + setState({ showAST: v }); + }} /> {state.showAST === 'es' && ( void; mode: FilterMode; }): JSX.Element { - const toNextMode = (): void => + const toNextMode = (): void => { setMode(filterModes[(filterModes.indexOf(mode) + 1) % filterModes.length]); + }; return (
  • diff --git a/packages/website/src/components/lib/createEventsBinder.ts b/packages/website/src/components/lib/createEventsBinder.ts index 6b5bfaecbee1..47cc37fd3d17 100644 --- a/packages/website/src/components/lib/createEventsBinder.ts +++ b/packages/website/src/components/lib/createEventsBinder.ts @@ -7,7 +7,9 @@ export function createEventsBinder void>(): { return { trigger(...args: Parameters): void { - events.forEach(cb => cb(...args)); + events.forEach(cb => { + cb(...args); + }); }, register(cb: T): () => void { events.add(cb); diff --git a/packages/website/src/components/linter/bridge.ts b/packages/website/src/components/linter/bridge.ts index 4a4d52e44637..03ffb58e33aa 100644 --- a/packages/website/src/components/linter/bridge.ts +++ b/packages/website/src/components/linter/bridge.ts @@ -48,7 +48,9 @@ export function createFileSystem( ): void => { fileWatcherCallbacks.forEach((callbacks, key) => { if (key.test(path)) { - callbacks.forEach(cb => cb(path, type)); + callbacks.forEach(cb => { + cb(path, type); + }); } }); }; diff --git a/packages/website/src/hooks/useBool.ts b/packages/website/src/hooks/useBool.ts index b06c9c40e5a4..c4e6c569e8da 100644 --- a/packages/website/src/hooks/useBool.ts +++ b/packages/website/src/hooks/useBool.ts @@ -6,10 +6,9 @@ export function useBool( ): [boolean, () => void, Dispatch>] { const [value, setValue] = useState(initialState); - const toggle = useCallback( - (): void => setValue(currentValue => !currentValue), - [], - ); + const toggle = useCallback((): void => { + setValue(currentValue => !currentValue); + }, []); return [value, toggle, setValue]; } diff --git a/packages/website/src/hooks/useMediaQuery.ts b/packages/website/src/hooks/useMediaQuery.ts index 1bd928c4a4b2..964797e20ddd 100644 --- a/packages/website/src/hooks/useMediaQuery.ts +++ b/packages/website/src/hooks/useMediaQuery.ts @@ -17,8 +17,9 @@ const useMediaQuery = (mediaQuery: string): boolean => { useEffect(() => { const mediaQueryList = window.matchMedia(mediaQuery); - const documentChangeHandler = (): void => + const documentChangeHandler = (): void => { setIsVerified(!!mediaQueryList.matches); + }; try { mediaQueryList.addEventListener('change', documentChangeHandler); diff --git a/packages/website/src/theme/CodeBlock/Content/String.tsx b/packages/website/src/theme/CodeBlock/Content/String.tsx index 46ba5682c281..94fe5b84db61 100644 --- a/packages/website/src/theme/CodeBlock/Content/String.tsx +++ b/packages/website/src/theme/CodeBlock/Content/String.tsx @@ -107,7 +107,9 @@ export default function CodeBlockString({ {(wordWrap.isEnabled || wordWrap.isCodeScrollable) && ( wordWrap.toggle()} + onClick={(): void => { + wordWrap.toggle(); + }} isEnabled={wordWrap.isEnabled} /> )} From f237b10d5218ece022275a5a6f26cd74e4deea33 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Mon, 26 Jun 2023 15:16:21 -0700 Subject: [PATCH 2/6] Reduced scope of changes --- .eslintrc.js | 7 +- packages/ast-spec/tests/fixtures.test.ts | 4 +- .../src/rules/no-poorly-typed-ts-props.ts | 3 +- .../src/rules/plugin-test-formatting.ts | 18 +- .../src/rules/prefer-ast-types-enum.ts | 3 +- packages/eslint-plugin/rules.d.ts | 7 +- packages/eslint-plugin/src/rules/ban-types.ts | 3 +- .../src/rules/consistent-type-exports.ts | 2 +- .../src/rules/consistent-type-imports.ts | 2 +- .../rules/explicit-function-return-type.ts | 12 +- .../rules/explicit-module-boundary-types.ts | 52 ++---- .../src/rules/func-call-spacing.ts | 3 +- packages/eslint-plugin/src/rules/indent.ts | 28 +-- .../src/rules/lines-around-comment.ts | 2 +- .../src/rules/member-ordering.ts | 3 +- .../rules/naming-convention-utils/format.ts | 8 +- .../src/rules/no-confusing-void-expression.ts | 18 +- .../src/rules/no-dupe-class-members.ts | 2 +- .../src/rules/no-extra-parens.ts | 93 ++++------ .../src/rules/no-restricted-imports.ts | 12 +- .../eslint-plugin/src/rules/no-type-alias.ts | 5 +- .../src/rules/no-unnecessary-condition.ts | 26 +-- .../src/rules/no-unsafe-return.ts | 6 +- .../src/rules/prefer-regexp-exec.ts | 15 +- .../rules/prefer-string-starts-ends-with.ts | 3 +- .../src/rules/promise-function-async.ts | 3 +- .../src/rules/restrict-plus-operands.ts | 6 +- .../src/rules/sort-type-constituents.ts | 3 +- .../src/util/collectUnusedVariables.ts | 2 +- packages/eslint-plugin/tests/docs.test.ts | 6 +- .../eslint-plugin/tools/generate-configs.ts | 4 +- .../src/index.ts | 4 +- packages/rule-tester/src/RuleTester.ts | 7 +- .../src/types/DependencyConstraint.ts | 7 +- .../rule-tester/src/utils/config-validator.ts | 5 +- .../src/utils/validationHelpers.ts | 12 +- packages/rule-tester/tests/RuleTester.test.ts | 10 +- .../src/referencer/ClassVisitor.ts | 24 +-- .../src/referencer/Referencer.ts | 4 +- packages/scope-manager/src/scope/ScopeBase.ts | 4 +- packages/scope-manager/src/scope/WithScope.ts | 4 +- .../es6-destructuring-assignments.test.ts | 131 +++++++------- .../implicit-global-reference.test.ts | 43 ++--- .../tests/eslint-scope/references.test.ts | 18 +- packages/scope-manager/tests/fixtures.test.ts | 4 +- .../type-utils/tests/isTypeReadonly.test.ts | 15 +- packages/types/tools/copy-ast-spec.ts | 12 +- .../create-program/createProjectProgram.ts | 2 +- .../getWatchProgramsForProjects.ts | 18 +- .../src/create-program/useProvidedPrograms.ts | 2 +- packages/typescript-estree/src/node-utils.ts | 2 +- packages/typescript-estree/src/parser.ts | 2 +- .../typescript-estree/src/simple-traverse.ts | 10 +- .../tests/lib/persistentParse.test.ts | 160 +++++------------- .../tests/lib/semanticInfo.test.ts | 4 +- packages/utils/src/json-schema.ts | 30 +++- packages/utils/src/ts-eslint/CLIEngine.ts | 10 +- packages/utils/src/ts-eslint/Linter.ts | 8 +- packages/utils/src/ts-eslint/Rule.ts | 5 +- packages/utils/src/ts-eslint/SourceCode.ts | 4 +- .../tests/eslint-utils/nullThrows.test.ts | 6 +- packages/visitor-keys/src/visitor-keys.ts | 4 +- .../src/components/OptionsSelector.tsx | 20 +-- .../website/src/components/Playground.tsx | 4 +- .../src/components/RulesTable/index.tsx | 29 +--- .../src/components/config/ConfigEditor.tsx | 13 +- .../src/components/editor/LoadedEditor.tsx | 40 ++--- .../src/components/inputs/Checkbox.tsx | 6 +- .../website/src/components/inputs/Text.tsx | 4 +- .../src/components/layout/EditorTabs.tsx | 4 +- .../src/components/lib/createEventsBinder.ts | 4 +- .../website/src/components/linter/bridge.ts | 4 +- packages/website/src/hooks/useBool.ts | 7 +- packages/website/src/hooks/useMediaQuery.ts | 3 +- .../src/theme/CodeBlock/Content/String.tsx | 4 +- 75 files changed, 435 insertions(+), 639 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 434309cc8080..9795cfb5792d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -53,9 +53,14 @@ module.exports = { // make sure we're not leveraging any deprecated APIs 'deprecation/deprecation': 'error', - // TODO(#7138): Enable this soon ✨ + // TODO(#7138): Investigate enabling these soon ✨ + '@typescript-eslint/consistent-indexed-object-style': 'off', '@typescript-eslint/prefer-nullish-coalescing': 'off', + // TODO(#7130): Investigate changing these in or removing these from presets + '@typescript-eslint/no-confusing-void-expression': 'off', + '@typescript-eslint/prefer-string-starts-ends-with': 'off', + // // our plugin :D // diff --git a/packages/ast-spec/tests/fixtures.test.ts b/packages/ast-spec/tests/fixtures.test.ts index d04b37b48569..6462d4ab03a6 100644 --- a/packages/ast-spec/tests/fixtures.test.ts +++ b/packages/ast-spec/tests/fixtures.test.ts @@ -333,9 +333,7 @@ function nestDescribe(fixture: Fixture, segments = fixture.segments): void { } describe('AST Fixtures', () => { - FIXTURES.forEach(f => { - nestDescribe(f); - }); + FIXTURES.forEach(f => nestDescribe(f)); // once we've run all the tests, snapshot the list of fixtures that have differences for easy reference it('List fixtures with AST differences', () => { diff --git a/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts b/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts index ff5d705d1ede..7b34aa0fd260 100644 --- a/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts +++ b/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts @@ -78,7 +78,7 @@ export default createRule({ continue; } - context.report({ + return context.report({ node, messageId: banned.fixWith ? 'doNotUseWithFixer' : 'doNotUse', data: banned, @@ -96,7 +96,6 @@ export default createRule({ }, ], }); - return; } }, }; diff --git a/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts b/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts index 0df473be52e5..be81846a116a 100644 --- a/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts +++ b/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts @@ -267,7 +267,7 @@ export default createRule({ if (literal.loc.end.line === literal.loc.start.line) { // don't use template strings for single line tests - context.report({ + return context.report({ node: literal, messageId: 'singleLineQuotes', fix(fixer) { @@ -288,7 +288,6 @@ export default createRule({ ]; }, }); - return; } const lines = text.split('\n'); @@ -299,7 +298,7 @@ export default createRule({ const isEndEmpty = lastLine.trimStart() === ''; if (!isStartEmpty || !isEndEmpty) { // multiline template strings must have an empty first/last line - context.report({ + return context.report({ node: literal, messageId: 'templateLiteralEmptyEnds', *fix(fixer) { @@ -318,12 +317,11 @@ export default createRule({ } }, }); - return; } const parentIndent = getExpectedIndentForNode(literal, sourceCode.lines); if (lastLine.length !== parentIndent) { - context.report({ + return context.report({ node: literal, messageId: 'templateLiteralLastLineIndent', fix(fixer) { @@ -333,7 +331,6 @@ export default createRule({ ); }, }); - return; } // remove the empty lines @@ -349,14 +346,13 @@ export default createRule({ const requiresIndent = firstLineIndent.length > 0; if (requiresIndent) { if (firstLineIndent.length !== expectedIndent) { - context.report({ + return context.report({ node: literal, messageId: 'templateStringRequiresIndent', data: { indent: expectedIndent, }, }); - return; } // quick-and-dirty validation that lines are roughly indented correctly @@ -370,14 +366,13 @@ export default createRule({ const indent = matches[1]; if (indent.length < expectedIndent) { - context.report({ + return context.report({ node: literal, messageId: 'templateStringMinimumIndent', data: { indent: expectedIndent, }, }); - return; } } @@ -402,7 +397,7 @@ export default createRule({ .join('\n') : formatted; - context.report({ + return context.report({ node: literal, messageId: isErrorTest ? 'invalidFormattingErrorTest' @@ -417,7 +412,6 @@ export default createRule({ ); }, }); - return; } } diff --git a/packages/eslint-plugin-internal/src/rules/prefer-ast-types-enum.ts b/packages/eslint-plugin-internal/src/rules/prefer-ast-types-enum.ts index 2499503ffa69..e042f328614e 100755 --- a/packages/eslint-plugin-internal/src/rules/prefer-ast-types-enum.ts +++ b/packages/eslint-plugin-internal/src/rules/prefer-ast-types-enum.ts @@ -28,7 +28,7 @@ export default createRule({ const report = ( enumName: 'AST_NODE_TYPES' | 'AST_TOKEN_TYPES' | 'DefinitionType', literal: TSESTree.StringLiteral, - ): void => { + ): void => context.report({ data: { enumName, literal: literal.value }, messageId: 'preferEnum', @@ -36,7 +36,6 @@ export default createRule({ fix: fixer => fixer.replaceText(literal, `${enumName}.${literal.value}`), }); - }; return { Literal(node: TSESTree.Literal): void { diff --git a/packages/eslint-plugin/rules.d.ts b/packages/eslint-plugin/rules.d.ts index fbbcb924410f..9a5272d205c3 100644 --- a/packages/eslint-plugin/rules.d.ts +++ b/packages/eslint-plugin/rules.d.ts @@ -37,9 +37,8 @@ This is likely not portable. A type annotation is necessary. ts(2742) import type { RuleModule } from '@typescript-eslint/utils/ts-eslint'; -export type TypeScriptESLintRules = Record< - string, - RuleModule ->; +export interface TypeScriptESLintRules { + [ruleName: string]: RuleModule; +} declare const rules: TypeScriptESLintRules; export = rules; diff --git a/packages/eslint-plugin/src/rules/ban-types.ts b/packages/eslint-plugin/src/rules/ban-types.ts index ac22a4c41305..1557e3f998f9 100644 --- a/packages/eslint-plugin/src/rules/ban-types.ts +++ b/packages/eslint-plugin/src/rules/ban-types.ts @@ -260,9 +260,8 @@ export default util.createRule({ TYPE_KEYWORDS, (acc: TSESLint.RuleListener, keyword) => { if (bannedTypes.has(keyword)) { - acc[TYPE_KEYWORDS[keyword]] = (node: TSESTree.Node): void => { + acc[TYPE_KEYWORDS[keyword]] = (node: TSESTree.Node): void => checkBannedTypes(node, keyword); - }; } return acc; diff --git a/packages/eslint-plugin/src/rules/consistent-type-exports.ts b/packages/eslint-plugin/src/rules/consistent-type-exports.ts index 3c496ee63d61..e65451ded1da 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-exports.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-exports.ts @@ -67,7 +67,7 @@ export default util.createRule({ create(context, [{ fixMixedExportsWithInlineTypeSpecifier }]) { const sourceCode = context.getSourceCode(); - const sourceExportsMap: Record = {}; + const sourceExportsMap: { [key: string]: SourceExports } = {}; const services = util.getParserServices(context); /** diff --git a/packages/eslint-plugin/src/rules/consistent-type-imports.ts b/packages/eslint-plugin/src/rules/consistent-type-imports.ts index 2dbf8f1893be..dfa5e48ed652 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-imports.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-imports.ts @@ -96,7 +96,7 @@ export default util.createRule({ const fixStyle = option.fixStyle ?? 'separate-type-imports'; const sourceCode = context.getSourceCode(); - const sourceImportsMap: Record = {}; + const sourceImportsMap: { [key: string]: SourceImports } = {}; return { ...(prefer === 'type-imports' diff --git a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts index 718173a0366e..e57465be8365 100644 --- a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts @@ -196,13 +196,13 @@ export default util.createRule({ return; } - checkFunctionReturnType(node, options, sourceCode, loc => { + checkFunctionReturnType(node, options, sourceCode, loc => context.report({ node, loc, messageId: 'missingReturnType', - }); - }); + }), + ); }, FunctionDeclaration(node): void { if (isAllowedFunction(node)) { @@ -212,13 +212,13 @@ export default util.createRule({ return; } - checkFunctionReturnType(node, options, sourceCode, loc => { + checkFunctionReturnType(node, options, sourceCode, loc => context.report({ node, loc, messageId: 'missingReturnType', - }); - }); + }), + ); }, }; }, diff --git a/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts b/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts index 1ff38c7efed2..d4a0efd56e54 100644 --- a/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts +++ b/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts @@ -212,10 +212,8 @@ export default util.createRule({ } return; - case AST_NODE_TYPES.TSParameterProperty: { - checkParameter(param.parameter); - return; - } + case AST_NODE_TYPES.TSParameterProperty: + return checkParameter(param.parameter); case AST_NODE_TYPES.AssignmentPattern: // ignored as it has a type via its assignment return; @@ -339,10 +337,8 @@ export default util.createRule({ switch (node.type) { case AST_NODE_TYPES.ArrowFunctionExpression: - case AST_NODE_TYPES.FunctionExpression: { - checkFunctionExpression(node); - return; - } + case AST_NODE_TYPES.FunctionExpression: + return checkFunctionExpression(node); case AST_NODE_TYPES.ArrayExpression: for (const element of node.elements) { @@ -357,10 +353,7 @@ export default util.createRule({ ) { return; } - { - checkNode(node.value); - return; - } + return checkNode(node.value); case AST_NODE_TYPES.ClassDeclaration: case AST_NODE_TYPES.ClassExpression: @@ -369,10 +362,8 @@ export default util.createRule({ } return; - case AST_NODE_TYPES.FunctionDeclaration: { - checkFunction(node); - return; - } + case AST_NODE_TYPES.FunctionDeclaration: + return checkFunction(node); case AST_NODE_TYPES.MethodDefinition: case AST_NODE_TYPES.TSAbstractMethodDefinition: @@ -382,15 +373,10 @@ export default util.createRule({ ) { return; } - { - checkNode(node.value); - return; - } + return checkNode(node.value); - case AST_NODE_TYPES.Identifier: { - followReference(node); - return; - } + case AST_NODE_TYPES.Identifier: + return followReference(node); case AST_NODE_TYPES.ObjectExpression: for (const property of node.properties) { @@ -398,15 +384,11 @@ export default util.createRule({ } return; - case AST_NODE_TYPES.Property: { - checkNode(node.value); - return; - } + case AST_NODE_TYPES.Property: + return checkNode(node.value); - case AST_NODE_TYPES.TSEmptyBodyFunctionExpression: { - checkEmptyBodyFunctionExpression(node); - return; - } + case AST_NODE_TYPES.TSEmptyBodyFunctionExpression: + return checkEmptyBodyFunctionExpression(node); case AST_NODE_TYPES.VariableDeclaration: for (const declaration of node.declarations) { @@ -414,10 +396,8 @@ export default util.createRule({ } return; - case AST_NODE_TYPES.VariableDeclarator: { - checkNode(node.init); - return; - } + case AST_NODE_TYPES.VariableDeclarator: + return checkNode(node.init); } } diff --git a/packages/eslint-plugin/src/rules/func-call-spacing.ts b/packages/eslint-plugin/src/rules/func-call-spacing.ts index 143fe13ac8a9..b72c54951f92 100644 --- a/packages/eslint-plugin/src/rules/func-call-spacing.ts +++ b/packages/eslint-plugin/src/rules/func-call-spacing.ts @@ -109,7 +109,7 @@ export default util.createRule({ if (option === 'never') { if (hasWhitespace) { - context.report({ + return context.report({ node, loc: lastCalleeToken.loc.start, messageId: 'unexpectedWhitespace', @@ -132,7 +132,6 @@ export default util.createRule({ return null; }, }); - return; } } else if (isOptionalCall) { // disallow: diff --git a/packages/eslint-plugin/src/rules/indent.ts b/packages/eslint-plugin/src/rules/indent.ts index 6e6f95da28a5..94c1899f2d43 100644 --- a/packages/eslint-plugin/src/rules/indent.ts +++ b/packages/eslint-plugin/src/rules/indent.ts @@ -191,12 +191,12 @@ export default util.createRule({ return; } - rules.VariableDeclaration(node); + return rules.VariableDeclaration(node); }, TSAsExpression(node: TSESTree.TSAsExpression) { // transform it to a BinaryExpression - rules['BinaryExpression, LogicalExpression']({ + return rules['BinaryExpression, LogicalExpression']({ type: AST_NODE_TYPES.BinaryExpression, operator: 'as', left: node.expression, @@ -212,7 +212,7 @@ export default util.createRule({ TSConditionalType(node: TSESTree.TSConditionalType) { // transform it to a ConditionalExpression - rules.ConditionalExpression({ + return rules.ConditionalExpression({ type: AST_NODE_TYPES.ConditionalExpression, test: { parent: node, @@ -242,7 +242,7 @@ export default util.createRule({ node: TSESTree.TSEnumDeclaration | TSESTree.TSTypeLiteral, ) { // transform it to an ObjectExpression - rules['ObjectExpression, ObjectPattern']({ + return rules['ObjectExpression, ObjectPattern']({ type: AST_NODE_TYPES.ObjectExpression, properties: ( node.members as (TSESTree.TSEnumMember | TSESTree.TypeElement)[] @@ -263,7 +263,7 @@ export default util.createRule({ // use VariableDeclaration instead of ImportDeclaration because it's essentially the same thing const { id, moduleReference } = node; - rules.VariableDeclaration({ + return rules.VariableDeclaration({ type: AST_NODE_TYPES.VariableDeclaration, kind: 'const' as const, declarations: [ @@ -314,7 +314,7 @@ export default util.createRule({ TSIndexedAccessType(node: TSESTree.TSIndexedAccessType) { // convert to a MemberExpression - rules['MemberExpression, JSXMemberExpression, MetaProperty']({ + return rules['MemberExpression, JSXMemberExpression, MetaProperty']({ type: AST_NODE_TYPES.MemberExpression, object: node.objectType as any, property: node.indexType as any, @@ -330,7 +330,7 @@ export default util.createRule({ TSInterfaceBody(node: TSESTree.TSInterfaceBody) { // transform it to an ClassBody - rules['BlockStatement, ClassBody']({ + return rules['BlockStatement, ClassBody']({ type: AST_NODE_TYPES.ClassBody, body: node.body.map( p => @@ -351,7 +351,9 @@ export default util.createRule({ node: TSESTree.TSInterfaceDeclaration, ) { // transform it to a ClassDeclaration - rules['ClassDeclaration[superClass], ClassExpression[superClass]']({ + return rules[ + 'ClassDeclaration[superClass], ClassExpression[superClass]' + ]({ type: AST_NODE_TYPES.ClassDeclaration, body: node.body as any, id: null, @@ -379,7 +381,7 @@ export default util.createRule({ )!; // transform it to an ObjectExpression - rules['ObjectExpression, ObjectPattern']({ + return rules['ObjectExpression, ObjectPattern']({ type: AST_NODE_TYPES.ObjectExpression, properties: [ { @@ -418,7 +420,7 @@ export default util.createRule({ TSModuleBlock(node: TSESTree.TSModuleBlock) { // transform it to a BlockStatement - rules['BlockStatement, ClassBody']({ + return rules['BlockStatement, ClassBody']({ type: AST_NODE_TYPES.BlockStatement, body: node.body as any, @@ -430,7 +432,7 @@ export default util.createRule({ }, TSQualifiedName(node: TSESTree.TSQualifiedName) { - rules['MemberExpression, JSXMemberExpression, MetaProperty']({ + return rules['MemberExpression, JSXMemberExpression, MetaProperty']({ type: AST_NODE_TYPES.MemberExpression, object: node.left as any, property: node.right as any, @@ -446,7 +448,7 @@ export default util.createRule({ TSTupleType(node: TSESTree.TSTupleType) { // transform it to an ArrayExpression - rules['ArrayExpression, ArrayPattern']({ + return rules['ArrayExpression, ArrayPattern']({ type: AST_NODE_TYPES.ArrayExpression, elements: node.elementTypes as any, @@ -466,7 +468,7 @@ export default util.createRule({ // JSX is about the closest we can get because the angle brackets // it's not perfect but it works! - rules.JSXOpeningElement({ + return rules.JSXOpeningElement({ type: AST_NODE_TYPES.JSXOpeningElement, selfClosing: false, name: name as any, diff --git a/packages/eslint-plugin/src/rules/lines-around-comment.ts b/packages/eslint-plugin/src/rules/lines-around-comment.ts index e052a12325a6..f7cdef33b2e4 100644 --- a/packages/eslint-plugin/src/rules/lines-around-comment.ts +++ b/packages/eslint-plugin/src/rules/lines-around-comment.ts @@ -403,7 +403,7 @@ export default util.createRule({ } } } - context.report(descriptor); + return context.report(descriptor); }; const customContext = { report: customReport }; diff --git a/packages/eslint-plugin/src/rules/member-ordering.ts b/packages/eslint-plugin/src/rules/member-ordering.ts index b5ef0346f4cc..29b748e88cfe 100644 --- a/packages/eslint-plugin/src/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/rules/member-ordering.ts @@ -832,7 +832,7 @@ export default util.createRule({ i && isMemberOptional(member) !== isMemberOptional(members[i - 1]), ); - const report = (member: Member): void => { + const report = (member: Member): void => context.report({ messageId: 'incorrectRequiredMembersOrder', loc: member.loc, @@ -842,7 +842,6 @@ export default util.createRule({ optionalityOrder === 'required-first' ? 'required' : 'optional', }, }); - }; // if the optionality of the first item is correct (based on optionalityOrder) // then the first 0 inclusive to switchIndex exclusive members all diff --git a/packages/eslint-plugin/src/rules/naming-convention-utils/format.ts b/packages/eslint-plugin/src/rules/naming-convention-utils/format.ts index b74b1b688a5a..d3db62399eaa 100644 --- a/packages/eslint-plugin/src/rules/naming-convention-utils/format.ts +++ b/packages/eslint-plugin/src/rules/naming-convention-utils/format.ts @@ -17,26 +17,26 @@ https://gist.github.com/mathiasbynens/6334847 function isPascalCase(name: string): boolean { return ( name.length === 0 || - (name.startsWith(name[0].toUpperCase()) && !name.includes('_')) + (name[0] === name[0].toUpperCase() && !name.includes('_')) ); } function isStrictPascalCase(name: string): boolean { return ( name.length === 0 || - (name.startsWith(name[0].toUpperCase()) && hasStrictCamelHumps(name, true)) + (name[0] === name[0].toUpperCase() && hasStrictCamelHumps(name, true)) ); } function isCamelCase(name: string): boolean { return ( name.length === 0 || - (name.startsWith(name[0].toLowerCase()) && !name.includes('_')) + (name[0] === name[0].toLowerCase() && !name.includes('_')) ); } function isStrictCamelCase(name: string): boolean { return ( name.length === 0 || - (name.startsWith(name[0].toLowerCase()) && hasStrictCamelHumps(name, false)) + (name[0] === name[0].toLowerCase() && hasStrictCamelHumps(name, false)) ); } diff --git a/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts b/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts index f4f115c297d4..ab6f08c1bb55 100644 --- a/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts +++ b/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts @@ -105,17 +105,16 @@ export default util.createRule({ if (options.ignoreVoidOperator) { // handle wrapping with `void` - context.report({ + return context.report({ node, messageId: 'invalidVoidExprArrowWrapVoid', fix: wrapVoidFix, }); - return; } // handle wrapping with braces const arrowFunction = invalidAncestor; - context.report({ + return context.report({ node, messageId: 'invalidVoidExprArrow', fix(fixer) { @@ -139,7 +138,6 @@ export default util.createRule({ return fixer.replaceText(arrowBody, newArrowBodyText); }, }); - return; } if (invalidAncestor.type === AST_NODE_TYPES.ReturnStatement) { @@ -147,19 +145,18 @@ export default util.createRule({ if (options.ignoreVoidOperator) { // handle wrapping with `void` - context.report({ + return context.report({ node, messageId: 'invalidVoidExprReturnWrapVoid', fix: wrapVoidFix, }); - return; } const returnStmt = invalidAncestor; if (isFinalReturn(returnStmt)) { // remove the `return` keyword - context.report({ + return context.report({ node, messageId: 'invalidVoidExprReturnLast', fix(fixer) { @@ -173,11 +170,10 @@ export default util.createRule({ return fixer.replaceText(returnStmt, newReturnStmtText); }, }); - return; } // move before the `return` keyword - context.report({ + return context.report({ node, messageId: 'invalidVoidExprReturn', fix(fixer) { @@ -196,18 +192,16 @@ export default util.createRule({ return fixer.replaceText(returnStmt, newReturnStmtText); }, }); - return; } // handle generic case if (options.ignoreVoidOperator) { // this would be reported by this rule btw. such irony - context.report({ + return context.report({ node, messageId: 'invalidVoidExprWrapVoid', suggest: [{ messageId: 'voidExprWrapVoid', fix: wrapVoidFix }], }); - return; } context.report({ diff --git a/packages/eslint-plugin/src/rules/no-dupe-class-members.ts b/packages/eslint-plugin/src/rules/no-dupe-class-members.ts index 979161914baf..95689cae513c 100644 --- a/packages/eslint-plugin/src/rules/no-dupe-class-members.ts +++ b/packages/eslint-plugin/src/rules/no-dupe-class-members.ts @@ -40,7 +40,7 @@ export default util.createRule({ return; } - coreListener(node); + return coreListener(node); }; } diff --git a/packages/eslint-plugin/src/rules/no-extra-parens.ts b/packages/eslint-plugin/src/rules/no-extra-parens.ts index 535d319920bd..b3a150ad201e 100644 --- a/packages/eslint-plugin/src/rules/no-extra-parens.ts +++ b/packages/eslint-plugin/src/rules/no-extra-parens.ts @@ -41,27 +41,25 @@ export default util.createRule({ return; // ignore } if (isLeftTypeAssertion) { - rule({ + return rule({ ...node, left: { ...node.left, type: AST_NODE_TYPES.SequenceExpression as any, }, }); - return; } if (isRightTypeAssertion) { - rule({ + return rule({ ...node, right: { ...node.right, type: AST_NODE_TYPES.SequenceExpression as any, }, }); - return; } - rule(node); + return rule(node); } function callExp( node: TSESTree.CallExpression | TSESTree.NewExpression, @@ -70,14 +68,13 @@ export default util.createRule({ if (util.isTypeAssertion(node.callee)) { // reduces the precedence of the node so the rule thinks it needs to be wrapped - rule({ + return rule({ ...node, callee: { ...node.callee, type: AST_NODE_TYPES.SequenceExpression as any, }, }); - return; } if ( @@ -88,7 +85,7 @@ export default util.createRule({ param.type === AST_NODE_TYPES.TSArrayType, ) ) { - rule({ + return rule({ ...node, arguments: [ { @@ -97,10 +94,9 @@ export default util.createRule({ }, ], }); - return; } - rule(node); + return rule(node); } function unaryUpdateExpression( node: TSESTree.UnaryExpression | TSESTree.UpdateExpression, @@ -109,137 +105,125 @@ export default util.createRule({ if (util.isTypeAssertion(node.argument)) { // reduces the precedence of the node so the rule thinks it needs to be wrapped - rule({ + return rule({ ...node, argument: { ...node.argument, type: AST_NODE_TYPES.SequenceExpression as any, }, }); - return; } - rule(node); + return rule(node); } const overrides: TSESLint.RuleListener = { // ArrayExpression ArrowFunctionExpression(node) { if (!util.isTypeAssertion(node.body)) { - rules.ArrowFunctionExpression(node); - return; + return rules.ArrowFunctionExpression(node); } }, // AssignmentExpression AwaitExpression(node) { if (util.isTypeAssertion(node.argument)) { // reduces the precedence of the node so the rule thinks it needs to be wrapped - rules.AwaitExpression({ + return rules.AwaitExpression({ ...node, argument: { ...node.argument, type: AST_NODE_TYPES.SequenceExpression as any, }, }); - return; } - rules.AwaitExpression(node); + return rules.AwaitExpression(node); }, BinaryExpression: binaryExp, CallExpression: callExp, ClassDeclaration(node) { if (node.superClass?.type === AST_NODE_TYPES.TSAsExpression) { - rules.ClassDeclaration({ + return rules.ClassDeclaration({ ...node, superClass: { ...node.superClass, type: AST_NODE_TYPES.SequenceExpression as any, }, }); - return; } - rules.ClassDeclaration(node); + return rules.ClassDeclaration(node); }, ClassExpression(node) { if (node.superClass?.type === AST_NODE_TYPES.TSAsExpression) { - rules.ClassExpression({ + return rules.ClassExpression({ ...node, superClass: { ...node.superClass, type: AST_NODE_TYPES.SequenceExpression as any, }, }); - return; } - rules.ClassExpression(node); + return rules.ClassExpression(node); }, ConditionalExpression(node) { // reduces the precedence of the node so the rule thinks it needs to be wrapped if (util.isTypeAssertion(node.test)) { - rules.ConditionalExpression({ + return rules.ConditionalExpression({ ...node, test: { ...node.test, type: AST_NODE_TYPES.SequenceExpression as any, }, }); - return; } if (util.isTypeAssertion(node.consequent)) { - rules.ConditionalExpression({ + return rules.ConditionalExpression({ ...node, consequent: { ...node.consequent, type: AST_NODE_TYPES.SequenceExpression as any, }, }); - return; } if (util.isTypeAssertion(node.alternate)) { // reduces the precedence of the node so the rule thinks it needs to be wrapped - rules.ConditionalExpression({ + return rules.ConditionalExpression({ ...node, alternate: { ...node.alternate, type: AST_NODE_TYPES.SequenceExpression as any, }, }); - return; } - rules.ConditionalExpression(node); + return rules.ConditionalExpression(node); }, // DoWhileStatement // ForIn and ForOf are guarded by eslint version ForStatement(node) { // make the rule skip the piece by removing it entirely if (node.init && util.isTypeAssertion(node.init)) { - rules.ForStatement({ + return rules.ForStatement({ ...node, init: null, }); - return; } if (node.test && util.isTypeAssertion(node.test)) { - rules.ForStatement({ + return rules.ForStatement({ ...node, test: null, }); - return; } if (node.update && util.isTypeAssertion(node.update)) { - rules.ForStatement({ + return rules.ForStatement({ ...node, update: null, }); - return; } - rules.ForStatement(node); + return rules.ForStatement(node); }, 'ForStatement > *.init:exit'(node: TSESTree.Node) { if (!util.isTypeAssertion(node)) { - rules['ForStatement > *.init:exit'](node); - return; + return rules['ForStatement > *.init:exit'](node); } }, // IfStatement @@ -247,17 +231,16 @@ export default util.createRule({ MemberExpression(node) { if (util.isTypeAssertion(node.object)) { // reduces the precedence of the node so the rule thinks it needs to be wrapped - rules.MemberExpression({ + return rules.MemberExpression({ ...node, object: { ...node.object, type: AST_NODE_TYPES.SequenceExpression as any, }, }); - return; } - rules.MemberExpression(node); + return rules.MemberExpression(node); }, NewExpression: callExp, // ObjectExpression @@ -265,21 +248,18 @@ export default util.createRule({ // SequenceExpression SpreadElement(node) { if (!util.isTypeAssertion(node.argument)) { - rules.SpreadElement(node); - return; + return rules.SpreadElement(node); } }, SwitchCase(node) { if (node.test && !util.isTypeAssertion(node.test)) { - rules.SwitchCase(node); - return; + return rules.SwitchCase(node); } }, // SwitchStatement ThrowStatement(node) { if (node.argument && !util.isTypeAssertion(node.argument)) { - rules.ThrowStatement(node); - return; + return rules.ThrowStatement(node); } }, UnaryExpression: unaryUpdateExpression, @@ -289,8 +269,7 @@ export default util.createRule({ // WithStatement - i'm not going to even bother implementing this terrible and never used feature YieldExpression(node) { if (node.argument && !util.isTypeAssertion(node.argument)) { - rules.YieldExpression(node); - return; + return rules.YieldExpression(node); } }, }; @@ -302,12 +281,12 @@ export default util.createRule({ return; } - rules.ForInStatement(node); + return rules.ForInStatement(node); }; overrides.ForOfStatement = function (node): void { if (util.isTypeAssertion(node.right)) { // makes the rule skip checking of the right - rules.ForOfStatement({ + return rules.ForOfStatement({ ...node, type: AST_NODE_TYPES.ForOfStatement, right: { @@ -315,10 +294,9 @@ export default util.createRule({ type: AST_NODE_TYPES.SequenceExpression as any, }, }); - return; } - rules.ForOfStatement(node); + return rules.ForOfStatement(node); }; } else { overrides['ForInStatement, ForOfStatement'] = function ( @@ -326,7 +304,7 @@ export default util.createRule({ ): void { if (util.isTypeAssertion(node.right)) { // makes the rule skip checking of the right - rules['ForInStatement, ForOfStatement']({ + return rules['ForInStatement, ForOfStatement']({ ...node, type: AST_NODE_TYPES.ForOfStatement as any, right: { @@ -334,10 +312,9 @@ export default util.createRule({ type: AST_NODE_TYPES.SequenceExpression as any, }, }); - return; } - rules['ForInStatement, ForOfStatement'](node); + return rules['ForInStatement, ForOfStatement'](node); }; } return Object.assign({}, rules, overrides); diff --git a/packages/eslint-plugin/src/rules/no-restricted-imports.ts b/packages/eslint-plugin/src/rules/no-restricted-imports.ts index 35c0174207eb..8c191dbaae9c 100644 --- a/packages/eslint-plugin/src/rules/no-restricted-imports.ts +++ b/packages/eslint-plugin/src/rules/no-restricted-imports.ts @@ -227,12 +227,10 @@ export default createRule({ !isAllowedTypeImportPath(importSource) && !isAllowedTypeImportPattern(importSource) ) { - rules.ImportDeclaration(node); - return; + return rules.ImportDeclaration(node); } } else { - rules.ImportDeclaration(node); - return; + return rules.ImportDeclaration(node); } }, 'ExportNamedDeclaration[source]'( @@ -246,12 +244,10 @@ export default createRule({ !isAllowedTypeImportPath(importSource) && !isAllowedTypeImportPattern(importSource) ) { - rules.ExportNamedDeclaration(node); - return; + return rules.ExportNamedDeclaration(node); } } else { - rules.ExportNamedDeclaration(node); - return; + return rules.ExportNamedDeclaration(node); } }, ExportAllDeclaration: rules.ExportAllDeclaration, diff --git a/packages/eslint-plugin/src/rules/no-type-alias.ts b/packages/eslint-plugin/src/rules/no-type-alias.ts index 8ed31e5f073b..cc568a6fa9db 100644 --- a/packages/eslint-plugin/src/rules/no-type-alias.ts +++ b/packages/eslint-plugin/src/rules/no-type-alias.ts @@ -188,17 +188,16 @@ export default util.createRule({ type: string, ): void { if (isRoot) { - context.report({ + return context.report({ node, messageId: 'noTypeAlias', data: { alias: type.toLowerCase(), }, }); - return; } - context.report({ + return context.report({ node, messageId: 'noCompositionAlias', data: { diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts index 5ec8ac5d674b..007a8a07a6d6 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts @@ -199,8 +199,7 @@ export default createRule({ node.type === AST_NODE_TYPES.UnaryExpression && node.operator === '!' ) { - checkNode(node.argument, true); - return; + return checkNode(node.argument, true); } // Since typescript array index signature types don't represent the @@ -220,8 +219,7 @@ export default createRule({ node.type === AST_NODE_TYPES.LogicalExpression && node.operator !== '??' ) { - checkNode(node.right); - return; + return checkNode(node.right); } const type = getConstrainedTypeAtLocation(services, node); @@ -437,8 +435,7 @@ export default createRule({ // Two special cases, where we can directly check the node that's returned: // () => something if (callback.body.type !== AST_NODE_TYPES.BlockStatement) { - checkNode(callback.body); - return; + return checkNode(callback.body); } // () => { return something; } const callbackBody = callback.body.body; @@ -447,8 +444,7 @@ export default createRule({ callbackBody[0].type === AST_NODE_TYPES.ReturnStatement && callbackBody[0].argument ) { - checkNode(callbackBody[0].argument); - return; + return checkNode(callbackBody[0].argument); } // Potential enhancement: could use code-path analysis to check // any function with a single return statement @@ -469,18 +465,16 @@ export default createRule({ return; } if (!returnTypes.some(isPossiblyFalsy)) { - context.report({ + return context.report({ node: callback, messageId: 'alwaysTruthyFunc', }); - return; } if (!returnTypes.some(isPossiblyTruthy)) { - context.report({ + return context.report({ node: callback, messageId: 'alwaysFalsyFunc', }); - return; } } } @@ -663,14 +657,10 @@ export default createRule({ AssignmentExpression: checkAssignmentExpression, BinaryExpression: checkIfBinaryExpressionIsNecessaryConditional, CallExpression: checkCallExpression, - ConditionalExpression: (node): void => { - checkNode(node.test); - }, + ConditionalExpression: (node): void => checkNode(node.test), DoWhileStatement: checkIfLoopIsNecessaryConditional, ForStatement: checkIfLoopIsNecessaryConditional, - IfStatement: (node): void => { - checkNode(node.test); - }, + IfStatement: (node): void => checkNode(node.test), LogicalExpression: checkLogicalExpressionForUnnecessaryConditionals, WhileStatement: checkIfLoopIsNecessaryConditional, 'MemberExpression[optional = true]': checkOptionalMemberExpression, diff --git a/packages/eslint-plugin/src/rules/no-unsafe-return.ts b/packages/eslint-plugin/src/rules/no-unsafe-return.ts index cb110f523e43..93a1226e9e4a 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-return.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-return.ts @@ -137,14 +137,13 @@ export default util.createRule({ } // If the function return type was not unknown/unknown[], mark usage as unsafeReturn. - context.report({ + return context.report({ node: reportingNode, messageId, data: { type: anyType === util.AnyType.Any ? 'any' : 'any[]', }, }); - return; } for (const signature of functionType.getCallSignatures()) { @@ -160,7 +159,7 @@ export default util.createRule({ } const { sender, receiver } = result; - context.report({ + return context.report({ node: reportingNode, messageId: 'unsafeReturnAssignment', data: { @@ -168,7 +167,6 @@ export default util.createRule({ receiver: checker.typeToString(receiver), }, }); - return; } } diff --git a/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts b/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts index 737761bb8366..8e61a735c13e 100644 --- a/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts +++ b/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts @@ -124,7 +124,7 @@ export default createRule({ } catch { return; } - context.report({ + return context.report({ node: memberNode.property, messageId: 'regExpExecOverStringMatch', fix: getWrappingFixer({ @@ -134,7 +134,6 @@ export default createRule({ wrap: objectCode => `${regExp.toString()}.exec(${objectCode})`, }), }); - return; } const argumentType = services.getTypeAtLocation(argumentNode); @@ -142,8 +141,8 @@ export default createRule({ tsutils.unionTypeParts(argumentType), ); switch (argumentTypes) { - case ArgumentType.RegExp: { - context.report({ + case ArgumentType.RegExp: + return context.report({ node: memberNode.property, messageId: 'regExpExecOverStringMatch', fix: getWrappingFixer({ @@ -154,11 +153,9 @@ export default createRule({ `${argumentCode}.exec(${objectCode})`, }), }); - return; - } - case ArgumentType.String: { - context.report({ + case ArgumentType.String: + return context.report({ node: memberNode.property, messageId: 'regExpExecOverStringMatch', fix: getWrappingFixer({ @@ -169,8 +166,6 @@ export default createRule({ `RegExp(${argumentCode}).exec(${objectCode})`, }), }); - return; - } } }, }; diff --git a/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts b/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts index f296bb3dfdc7..d6afab60146d 100644 --- a/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts +++ b/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts @@ -84,7 +84,8 @@ export default createRule({ return ( evaluated != null && typeof evaluated.value === 'string' && - evaluated.value.length === 1 + // checks if the string is a character long + evaluated.value[0] === evaluated.value ); } diff --git a/packages/eslint-plugin/src/rules/promise-function-async.ts b/packages/eslint-plugin/src/rules/promise-function-async.ts index 17d1d2c2a040..ba671d5929b0 100644 --- a/packages/eslint-plugin/src/rules/promise-function-async.ts +++ b/packages/eslint-plugin/src/rules/promise-function-async.ts @@ -137,12 +137,11 @@ export default util.createRule({ util.isTypeFlagSet(returnType, ts.TypeFlags.Any | ts.TypeFlags.Unknown) ) { // Report without auto fixer because the return type is unknown - context.report({ + return context.report({ messageId: 'missingAsync', node, loc: util.getFunctionHeadLoc(node, sourceCode), }); - return; } context.report({ diff --git a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts index 069111981700..6d2cc2222eaa 100644 --- a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts +++ b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts @@ -204,7 +204,7 @@ export default util.createRule({ isTypeFlagSetInUnion(baseType, ts.TypeFlags.StringLike) && isTypeFlagSetInUnion(otherType, ts.TypeFlags.NumberLike) ) { - context.report({ + return context.report({ data: { stringLike, left: typeChecker.typeToString(leftType), @@ -213,14 +213,13 @@ export default util.createRule({ messageId: 'mismatched', node, }); - return; } if ( isTypeFlagSetInUnion(baseType, ts.TypeFlags.NumberLike) && isTypeFlagSetInUnion(otherType, ts.TypeFlags.BigIntLike) ) { - context.report({ + return context.report({ data: { left: typeChecker.typeToString(leftType), right: typeChecker.typeToString(rightType), @@ -228,7 +227,6 @@ export default util.createRule({ messageId: 'bigintAndNumber', node, }); - return; } } } diff --git a/packages/eslint-plugin/src/rules/sort-type-constituents.ts b/packages/eslint-plugin/src/rules/sort-type-constituents.ts index cae6ff9d7401..ec54153e988d 100644 --- a/packages/eslint-plugin/src/rules/sort-type-constituents.ts +++ b/packages/eslint-plugin/src/rules/sort-type-constituents.ts @@ -233,7 +233,7 @@ export default util.createRule({ return fixer.replaceText(node, sorted); }; - context.report({ + return context.report({ node, messageId, data, @@ -250,7 +250,6 @@ export default util.createRule({ } : { fix }), }); - return; } } } diff --git a/packages/eslint-plugin/src/util/collectUnusedVariables.ts b/packages/eslint-plugin/src/util/collectUnusedVariables.ts index 05b158ef44ff..4d1b62b42341 100644 --- a/packages/eslint-plugin/src/util/collectUnusedVariables.ts +++ b/packages/eslint-plugin/src/util/collectUnusedVariables.ts @@ -437,7 +437,7 @@ function isExported(variable: TSESLint.Scope.Variable): boolean { return false; } - return node.parent!.type.startsWith('Export'); + return node.parent!.type.indexOf('Export') === 0; } return false; } diff --git a/packages/eslint-plugin/tests/docs.test.ts b/packages/eslint-plugin/tests/docs.test.ts index 5f912169edb0..a2bef8cac839 100644 --- a/packages/eslint-plugin/tests/docs.test.ts +++ b/packages/eslint-plugin/tests/docs.test.ts @@ -94,9 +94,9 @@ describe('Validating rule docs', () => { // Get all H2 headers objects as the other levels are variable by design. const headers = tokens.filter(tokenIsH2); - headers.forEach(header => { - expect(header.text).toBe(titleCase(header.text)); - }); + headers.forEach(header => + expect(header.text).toBe(titleCase(header.text)), + ); }); const importantHeadings = new Set([ diff --git a/packages/eslint-plugin/tools/generate-configs.ts b/packages/eslint-plugin/tools/generate-configs.ts index 8fac06d16687..5056bdb7de42 100644 --- a/packages/eslint-plugin/tools/generate-configs.ts +++ b/packages/eslint-plugin/tools/generate-configs.ts @@ -47,7 +47,9 @@ async function main(): Promise { const prettierConfig = prettier.resolveConfig.sync(__dirname); - type LinterConfigRules = Record; + interface LinterConfigRules { + [name: string]: TSESLint.Linter.RuleLevel; + } interface LinterConfig extends TSESLint.Linter.Config { extends?: string[] | string; diff --git a/packages/rule-schema-to-typescript-types/src/index.ts b/packages/rule-schema-to-typescript-types/src/index.ts index ef1e187c2a6f..43d16826ab30 100644 --- a/packages/rule-schema-to-typescript-types/src/index.ts +++ b/packages/rule-schema-to-typescript-types/src/index.ts @@ -69,7 +69,9 @@ function compileSchema( const refMap = new Map(); // we only support defs at the top level for simplicity - const defs = schema.$defs ?? schema.definitions; + const defs = (schema.$defs ?? schema.definitions) as + | Record + | undefined; if (defs) { for (const [defKey, defSchema] of Object.entries(defs)) { const typeName = toPascalCase(defKey); diff --git a/packages/rule-tester/src/RuleTester.ts b/packages/rule-tester/src/RuleTester.ts index e72f42dacd37..cc6577611378 100644 --- a/packages/rule-tester/src/RuleTester.ts +++ b/packages/rule-tester/src/RuleTester.ts @@ -530,9 +530,10 @@ export class RuleTester extends TestFramework { if (ajv.errors) { const errors = ajv.errors .map(error => { - const field = error.dataPath.startsWith('.') - ? error.dataPath.slice(1) - : error.dataPath; + const field = + error.dataPath[0] === '.' + ? error.dataPath.slice(1) + : error.dataPath; return `\t${field}: ${error.message}`; }) diff --git a/packages/rule-tester/src/types/DependencyConstraint.ts b/packages/rule-tester/src/types/DependencyConstraint.ts index f02f51c4583a..ecb86e912cdb 100644 --- a/packages/rule-tester/src/types/DependencyConstraint.ts +++ b/packages/rule-tester/src/types/DependencyConstraint.ts @@ -12,4 +12,9 @@ export type AtLeastVersionConstraint = export type VersionConstraint = | AtLeastVersionConstraint | SemverVersionConstraint; -export type DependencyConstraint = Readonly>; +export interface DependencyConstraint { + /** + * Passing a string for the value is shorthand for a '>=' constraint + */ + readonly [packageName: string]: VersionConstraint; +} diff --git a/packages/rule-tester/src/utils/config-validator.ts b/packages/rule-tester/src/utils/config-validator.ts index 816aed3f4c41..ef88f7e664eb 100644 --- a/packages/rule-tester/src/utils/config-validator.ts +++ b/packages/rule-tester/src/utils/config-validator.ts @@ -227,9 +227,8 @@ function formatErrors(errors: AjvErrorObject[]): string { return `Property "${formattedField}" is the wrong type (expected ${formattedExpectedType} but got \`${formattedValue}\`)`; } - const field = error.dataPath.startsWith('.') - ? error.dataPath.slice(1) - : error.dataPath; + const field = + error.dataPath[0] === '.' ? error.dataPath.slice(1) : error.dataPath; return `"${field}" ${error.message}. Value: ${JSON.stringify( error.data, diff --git a/packages/rule-tester/src/utils/validationHelpers.ts b/packages/rule-tester/src/utils/validationHelpers.ts index 1156c9968f59..33fd0c234de8 100644 --- a/packages/rule-tester/src/utils/validationHelpers.ts +++ b/packages/rule-tester/src/utils/validationHelpers.ts @@ -111,16 +111,10 @@ export function wrapParser(parser: Linter.ParserModule): Linter.ParserModule { simpleTraverse(ast, { visitorKeys: visitorKeys, - enter: node => { - defineStartEndAsError('node', node); - }, - }); - ast.tokens?.forEach(token => { - defineStartEndAsError('token', token); - }); - ast.comments?.forEach(comment => { - defineStartEndAsError('token', comment); + enter: node => defineStartEndAsError('node', node), }); + ast.tokens?.forEach(token => defineStartEndAsError('token', token)); + ast.comments?.forEach(comment => defineStartEndAsError('token', comment)); } if ('parseForESLint' in parser) { diff --git a/packages/rule-tester/tests/RuleTester.test.ts b/packages/rule-tester/tests/RuleTester.test.ts index ec2c65e5af73..93f9f6d35d24 100644 --- a/packages/rule-tester/tests/RuleTester.test.ts +++ b/packages/rule-tester/tests/RuleTester.test.ts @@ -60,9 +60,7 @@ jest.mock('@typescript-eslint/parser', () => { /* eslint-disable jest/prefer-spy-on -- we need to specifically assign to the properties or else it will use the global value and register actual tests! */ -const IMMEDIATE_CALLBACK: RuleTesterTestFrameworkFunctionBase = (_, cb) => { - cb(); -}; +const IMMEDIATE_CALLBACK: RuleTesterTestFrameworkFunctionBase = (_, cb) => cb(); RuleTester.afterAll = jest.fn(/* intentionally don't immediate callback here */); RuleTester.describe = jest.fn(IMMEDIATE_CALLBACK); @@ -307,7 +305,7 @@ describe('RuleTester', () => { }, }); - expect(() => { + expect(() => ruleTester.run('my-rule', NOOP_RULE, { valid: [ { @@ -317,8 +315,8 @@ describe('RuleTester', () => { ], invalid: [], - }); - }).toThrowErrorMatchingInlineSnapshot( + }), + ).toThrowErrorMatchingInlineSnapshot( `"Do not set the parser at the test level unless you want to use a parser other than "@typescript-eslint/parser""`, ); }); diff --git a/packages/scope-manager/src/referencer/ClassVisitor.ts b/packages/scope-manager/src/referencer/ClassVisitor.ts index 46e729a539de..6123ab15e794 100644 --- a/packages/scope-manager/src/referencer/ClassVisitor.ts +++ b/packages/scope-manager/src/referencer/ClassVisitor.ts @@ -57,9 +57,7 @@ class ClassVisitor extends Visitor { .defineIdentifier(node.id, new ClassNameDefinition(node.id, node)); } - node.decorators.forEach(d => { - this.#referencer.visit(d); - }); + node.decorators.forEach(d => this.#referencer.visit(d)); this.#referencer.scopeManager.nestClassScope(node); @@ -77,9 +75,7 @@ class ClassVisitor extends Visitor { this.visitType(node.typeParameters); // then the usages this.visitType(node.superTypeArguments); - node.implements?.forEach(imp => { - this.visitType(imp); - }); + node.implements?.forEach(imp => this.visitType(imp)); this.visit(node.body); @@ -223,9 +219,7 @@ class ClassVisitor extends Visitor { { processRightHandNodes: true }, ); this.visitFunctionParameterTypeAnnotation(param, withMethodDecorators); - param.decorators.forEach(d => { - this.visit(d); - }); + param.decorators.forEach(d => this.visit(d)); } this.visitMetadataType(node.returnType, withMethodDecorators); @@ -277,9 +271,7 @@ class ClassVisitor extends Visitor { } } - node.decorators.forEach(d => { - this.#referencer.visit(d); - }); + node.decorators.forEach(d => this.#referencer.visit(d)); } protected visitMethod(node: TSESTree.MethodDefinition): void { @@ -293,9 +285,7 @@ class ClassVisitor extends Visitor { this.#referencer.visit(node.value); } - node.decorators.forEach(d => { - this.#referencer.visit(d); - }); + node.decorators.forEach(d => this.#referencer.visit(d)); } protected visitType(node: TSESTree.Node | null | undefined): void { @@ -399,9 +389,7 @@ class ClassVisitor extends Visitor { protected StaticBlock(node: TSESTree.StaticBlock): void { this.#referencer.scopeManager.nestClassStaticBlockScope(node); - node.body.forEach(b => { - this.visit(b); - }); + node.body.forEach(b => this.visit(b)); this.#referencer.close(node); } diff --git a/packages/scope-manager/src/referencer/Referencer.ts b/packages/scope-manager/src/referencer/Referencer.ts index a5c1f55fbb6c..38e4a0d2adac 100644 --- a/packages/scope-manager/src/referencer/Referencer.ts +++ b/packages/scope-manager/src/referencer/Referencer.ts @@ -269,9 +269,7 @@ class Referencer extends Visitor { { processRightHandNodes: true }, ); this.visitFunctionParameterTypeAnnotation(param); - param.decorators.forEach(d => { - this.visit(d); - }); + param.decorators.forEach(d => this.visit(d)); } this.visitType(node.returnType); diff --git a/packages/scope-manager/src/scope/ScopeBase.ts b/packages/scope-manager/src/scope/ScopeBase.ts index fb5110297368..81c712dff389 100644 --- a/packages/scope-manager/src/scope/ScopeBase.ts +++ b/packages/scope-manager/src/scope/ScopeBase.ts @@ -371,9 +371,7 @@ abstract class ScopeBase< // Try Resolving all references in this scope. assert(this.leftToResolve); - this.leftToResolve.forEach(ref => { - closeRef(ref, scopeManager); - }); + this.leftToResolve.forEach(ref => closeRef(ref, scopeManager)); this.leftToResolve = null; return this.upper; diff --git a/packages/scope-manager/src/scope/WithScope.ts b/packages/scope-manager/src/scope/WithScope.ts index 9ab1a377697b..7058ab70faa5 100644 --- a/packages/scope-manager/src/scope/WithScope.ts +++ b/packages/scope-manager/src/scope/WithScope.ts @@ -23,9 +23,7 @@ class WithScope extends ScopeBase< return super.close(scopeManager); } assert(this.leftToResolve); - this.leftToResolve.forEach(ref => { - this.delegateToUpperScope(ref); - }); + this.leftToResolve.forEach(ref => this.delegateToUpperScope(ref)); this.leftToResolve = null; return this.upper; } diff --git a/packages/scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts b/packages/scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts index 5054bba01d39..20e73e1f485b 100644 --- a/packages/scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts +++ b/packages/scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/dot-notation -- ['implicit'] is private */ import { expectToBeForScope, expectToBeFunctionScope, @@ -24,8 +25,8 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(1); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('array'); + expect(scope['implicit'].leftToBeResolved).toHaveLength(1); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -64,8 +65,8 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(1); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('array'); + expect(scope['implicit'].leftToBeResolved).toHaveLength(1); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('array'); scope = scopeManager.scopes[2]; variables = getRealVariables(scope.variables); @@ -104,9 +105,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(2); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('d'); - expect(scope.implicit.leftToBeResolved[1].identifier.name).toBe('array'); + expect(scope['implicit'].leftToBeResolved).toHaveLength(2); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('d'); + expect(scope['implicit'].leftToBeResolved[1].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -154,11 +155,11 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(2); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('d'); - expectToBeForScope(scope.implicit.leftToBeResolved[0].from); - expect(scope.implicit.leftToBeResolved[1].identifier.name).toBe('array'); - expectToBeForScope(scope.implicit.leftToBeResolved[1].from); + expect(scope['implicit'].leftToBeResolved).toHaveLength(2); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('d'); + expectToBeForScope(scope['implicit'].leftToBeResolved[0].from); + expect(scope['implicit'].leftToBeResolved[1].identifier.name).toBe('array'); + expectToBeForScope(scope['implicit'].leftToBeResolved[1].from); scope = scopeManager.scopes[2]; variables = getRealVariables(scope.variables); @@ -210,10 +211,10 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(3); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('d'); - expect(scope.implicit.leftToBeResolved[1].identifier.name).toBe('e'); - expect(scope.implicit.leftToBeResolved[2].identifier.name).toBe('array'); + expect(scope['implicit'].leftToBeResolved).toHaveLength(3); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('d'); + expect(scope['implicit'].leftToBeResolved[1].identifier.name).toBe('e'); + expect(scope['implicit'].leftToBeResolved[2].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -277,13 +278,13 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(3); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('d'); - expectToBeForScope(scope.implicit.leftToBeResolved[0].from); - expect(scope.implicit.leftToBeResolved[1].identifier.name).toBe('e'); - expectToBeForScope(scope.implicit.leftToBeResolved[1].from); - expect(scope.implicit.leftToBeResolved[2].identifier.name).toBe('array'); - expectToBeForScope(scope.implicit.leftToBeResolved[2].from); + expect(scope['implicit'].leftToBeResolved).toHaveLength(3); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('d'); + expectToBeForScope(scope['implicit'].leftToBeResolved[0].from); + expect(scope['implicit'].leftToBeResolved[1].identifier.name).toBe('e'); + expectToBeForScope(scope['implicit'].leftToBeResolved[1].from); + expect(scope['implicit'].leftToBeResolved[2].identifier.name).toBe('array'); + expectToBeForScope(scope['implicit'].leftToBeResolved[2].from); scope = scopeManager.scopes[2]; variables = getRealVariables(scope.variables); @@ -348,9 +349,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(2); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('d'); - expect(scope.implicit.leftToBeResolved[1].identifier.name).toBe('array'); + expect(scope['implicit'].leftToBeResolved).toHaveLength(2); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('d'); + expect(scope['implicit'].leftToBeResolved[1].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -399,9 +400,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(2); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('d'); - expect(scope.implicit.leftToBeResolved[1].identifier.name).toBe('array'); + expect(scope['implicit'].leftToBeResolved).toHaveLength(2); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('d'); + expect(scope['implicit'].leftToBeResolved[1].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -445,8 +446,8 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(1); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('array'); + expect(scope['implicit'].leftToBeResolved).toHaveLength(1); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -485,8 +486,8 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(1); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('array'); + expect(scope['implicit'].leftToBeResolved).toHaveLength(1); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -522,8 +523,8 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(1); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('array'); + expect(scope['implicit'].leftToBeResolved).toHaveLength(1); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -570,8 +571,10 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(1); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('object'); + expect(scope['implicit'].leftToBeResolved).toHaveLength(1); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe( + 'object', + ); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -616,8 +619,10 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(1); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('object'); + expect(scope['implicit'].leftToBeResolved).toHaveLength(1); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe( + 'object', + ); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -673,9 +678,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(4); + expect(scope['implicit'].leftToBeResolved).toHaveLength(4); expect( - scope.implicit.leftToBeResolved.map(left => left.identifier.name), + scope['implicit'].leftToBeResolved.map(left => left.identifier.name), ).toEqual(['a', 'b', 'c', 'array']); scope = scopeManager.scopes[1]; @@ -713,8 +718,8 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(1); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('array'); + expect(scope['implicit'].leftToBeResolved).toHaveLength(1); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -755,9 +760,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(4); + expect(scope['implicit'].leftToBeResolved).toHaveLength(4); expect( - scope.implicit.leftToBeResolved.map(left => left.identifier.name), + scope['implicit'].leftToBeResolved.map(left => left.identifier.name), ).toEqual(['a', 'b', 'rest', 'array']); scope = scopeManager.scopes[1]; @@ -791,9 +796,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(6); + expect(scope['implicit'].leftToBeResolved).toHaveLength(6); expect( - scope.implicit.leftToBeResolved.map(left => left.identifier.name), + scope['implicit'].leftToBeResolved.map(left => left.identifier.name), ).toEqual(['a', 'b', 'c', 'd', 'rest', 'array']); scope = scopeManager.scopes[1]; @@ -832,9 +837,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(4); + expect(scope['implicit'].leftToBeResolved).toHaveLength(4); expect( - scope.implicit.leftToBeResolved.map(left => left.identifier.name), + scope['implicit'].leftToBeResolved.map(left => left.identifier.name), ).toEqual(['a', 'b', 'obj', 'array']); scope = scopeManager.scopes[1]; @@ -876,9 +881,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(4); + expect(scope['implicit'].leftToBeResolved).toHaveLength(4); expect( - scope.implicit.leftToBeResolved.map(left => left.identifier.name), + scope['implicit'].leftToBeResolved.map(left => left.identifier.name), ).toEqual(['shorthand', 'value', 'world', 'object']); scope = scopeManager.scopes[1]; @@ -921,9 +926,9 @@ describe('ES6 destructuring assignments', () => { expectToBeGlobalScope(scope); expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(0); - expect(scope.implicit.leftToBeResolved).toHaveLength(8); + expect(scope['implicit'].leftToBeResolved).toHaveLength(8); expect( - scope.implicit.leftToBeResolved.map(left => left.identifier.name), + scope['implicit'].leftToBeResolved.map(left => left.identifier.name), ).toEqual(['shorthand', 'a', 'b', 'c', 'd', 'e', 'world', 'object']); scope = scopeManager.scopes[1]; @@ -967,8 +972,8 @@ describe('ES6 destructuring assignments', () => { expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(1); expect(scope.references[0].identifier.name).toBe('array'); - expect(scope.implicit.leftToBeResolved).toHaveLength(1); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('array'); + expect(scope['implicit'].leftToBeResolved).toHaveLength(1); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -996,8 +1001,8 @@ describe('ES6 destructuring assignments', () => { expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(1); expect(scope.references[0].identifier.name).toBe('array'); - expect(scope.implicit.leftToBeResolved).toHaveLength(1); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('array'); + expect(scope['implicit'].leftToBeResolved).toHaveLength(1); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe('array'); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -1035,8 +1040,10 @@ describe('ES6 destructuring assignments', () => { expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(1); expect(scope.references[0].identifier.name).toBe('object'); - expect(scope.implicit.leftToBeResolved).toHaveLength(1); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('object'); + expect(scope['implicit'].leftToBeResolved).toHaveLength(1); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe( + 'object', + ); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); @@ -1069,8 +1076,10 @@ describe('ES6 destructuring assignments', () => { expect(variables).toHaveLength(0); expect(scope.references).toHaveLength(1); expect(scope.references[0].identifier.name).toBe('object'); - expect(scope.implicit.leftToBeResolved).toHaveLength(1); - expect(scope.implicit.leftToBeResolved[0].identifier.name).toBe('object'); + expect(scope['implicit'].leftToBeResolved).toHaveLength(1); + expect(scope['implicit'].leftToBeResolved[0].identifier.name).toBe( + 'object', + ); scope = scopeManager.scopes[1]; variables = getRealVariables(scope.variables); diff --git a/packages/scope-manager/tests/eslint-scope/implicit-global-reference.test.ts b/packages/scope-manager/tests/eslint-scope/implicit-global-reference.test.ts index a8aa5ea7b4fb..22f27ed5d663 100644 --- a/packages/scope-manager/tests/eslint-scope/implicit-global-reference.test.ts +++ b/packages/scope-manager/tests/eslint-scope/implicit-global-reference.test.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/dot-notation -- ['implicit'] is private */ import { DefinitionType } from '../../src/definition'; import { expectToBeGlobalScope, @@ -23,9 +24,9 @@ describe('implicit global reference', () => { ).toEqual([[[DefinitionType.Variable]]]); expectToBeGlobalScope(scopes[0]); - expect(scopes[0].implicit.variables.map(variable => variable.name)).toEqual( - [], - ); + expect( + scopes[0]['implicit'].variables.map(variable => variable.name), + ).toEqual([]); }); it('assignments global scope without definition', () => { @@ -45,9 +46,9 @@ describe('implicit global reference', () => { ).toEqual([[]]); expectToBeGlobalScope(scopes[0]); - expect(scopes[0].implicit.variables.map(variable => variable.name)).toEqual( - ['x'], - ); + expect( + scopes[0]['implicit'].variables.map(variable => variable.name), + ).toEqual(['x']); }); it('assignments global scope without definition eval', () => { @@ -69,9 +70,9 @@ describe('implicit global reference', () => { ).toEqual([[[DefinitionType.FunctionName]], [[]]]); expectToBeGlobalScope(scopes[0]); - expect(scopes[0].implicit.variables.map(variable => variable.name)).toEqual( - ['x'], - ); + expect( + scopes[0]['implicit'].variables.map(variable => variable.name), + ).toEqual(['x']); }); it('assignment leaks', () => { @@ -90,9 +91,9 @@ describe('implicit global reference', () => { ).toEqual([['outer'], ['arguments']]); expectToBeGlobalScope(scopes[0]); - expect(scopes[0].implicit.variables.map(variable => variable.name)).toEqual( - ['x'], - ); + expect( + scopes[0]['implicit'].variables.map(variable => variable.name), + ).toEqual(['x']); }); it("assignment doesn't leak", () => { @@ -114,9 +115,9 @@ describe('implicit global reference', () => { ).toEqual([['outer'], ['arguments', 'inner', 'x'], ['arguments']]); expectToBeGlobalScope(scopes[0]); - expect(scopes[0].implicit.variables.map(variable => variable.name)).toEqual( - [], - ); + expect( + scopes[0]['implicit'].variables.map(variable => variable.name), + ).toEqual([]); }); it('for-in-statement leaks', () => { @@ -135,9 +136,9 @@ describe('implicit global reference', () => { ).toEqual([['outer'], ['arguments'], []]); expectToBeGlobalScope(scopes[0]); - expect(scopes[0].implicit.variables.map(variable => variable.name)).toEqual( - ['x'], - ); + expect( + scopes[0]['implicit'].variables.map(variable => variable.name), + ).toEqual(['x']); }); it("for-in-statement doesn't leaks", () => { @@ -159,8 +160,8 @@ describe('implicit global reference', () => { ).toEqual([['outer'], ['arguments', 'inner', 'x'], ['arguments'], []]); expectToBeGlobalScope(scopes[0]); - expect(scopes[0].implicit.variables.map(variable => variable.name)).toEqual( - [], - ); + expect( + scopes[0]['implicit'].variables.map(variable => variable.name), + ).toEqual([]); }); }); diff --git a/packages/scope-manager/tests/eslint-scope/references.test.ts b/packages/scope-manager/tests/eslint-scope/references.test.ts index 22fed597c3e7..0b49cab0f7f5 100644 --- a/packages/scope-manager/tests/eslint-scope/references.test.ts +++ b/packages/scope-manager/tests/eslint-scope/references.test.ts @@ -447,7 +447,7 @@ describe('References:', () => { 'new function({b: a = 0} = {}) {}', ]; - trueCodes.forEach(code => { + trueCodes.forEach(code => it(`"${code}", all references should be true.`, () => { const { scopeManager } = parseAndAnalyze(code); @@ -464,8 +464,8 @@ describe('References:', () => { expect(reference.isWrite()).toBeTruthy(); expect(reference.init).toBeTruthy(); }); - }); - }); + }), + ); let falseCodes = [ 'let a; a = 0;', @@ -481,7 +481,7 @@ describe('References:', () => { 'let a; for ({a = 0} in []);', ]; - falseCodes.forEach(code => { + falseCodes.forEach(code => it(`"${code}", all references should be false.`, () => { const { scopeManager } = parseAndAnalyze(code); @@ -498,8 +498,8 @@ describe('References:', () => { expect(reference.isWrite()).toBeTruthy(); expect(reference.init).toBeFalsy(); }); - }); - }); + }), + ); falseCodes = [ 'let a; let b = a;', @@ -517,7 +517,7 @@ describe('References:', () => { 'let a; a.foo = 0;', 'let a,b; b = a.foo;', ]; - falseCodes.forEach(code => { + falseCodes.forEach(code => it(`"${code}", readonly references of "a" should be undefined.`, () => { const { scopeManager } = parseAndAnalyze(code); @@ -537,8 +537,8 @@ describe('References:', () => { expect(reference.isRead()).toBeTruthy(); expect(reference.init).toBeUndefined(); }); - }); - }); + }), + ); }); describe('When emitDecoratorMetadata is true', () => { diff --git a/packages/scope-manager/tests/fixtures.test.ts b/packages/scope-manager/tests/fixtures.test.ts index 85cc8a3cd7e2..9f628bfe41e8 100644 --- a/packages/scope-manager/tests/fixtures.test.ts +++ b/packages/scope-manager/tests/fixtures.test.ts @@ -172,9 +172,7 @@ function nestDescribe( } } -fixtures.forEach(f => { - nestDescribe(f); -}); +fixtures.forEach(f => nestDescribe(f)); if (ONLY === '') { // ensure that the snapshots are cleaned up, because jest-specific-snapshot won't do this check diff --git a/packages/type-utils/tests/isTypeReadonly.test.ts b/packages/type-utils/tests/isTypeReadonly.test.ts index c88970dc8975..2adfaaec7aa8 100644 --- a/packages/type-utils/tests/isTypeReadonly.test.ts +++ b/packages/type-utils/tests/isTypeReadonly.test.ts @@ -139,15 +139,13 @@ describe('isTypeReadonly', () => { describe('is readonly circular', () => { const runTests = runTestIsReadonly; - it('handles circular readonly PropertySignature inside a readonly IndexSignature', () => { - runTests('interface Test { readonly [key: string]: Test };'); - }); + it('handles circular readonly PropertySignature inside a readonly IndexSignature', () => + runTests('interface Test { readonly [key: string]: Test };')); - it('handles circular readonly PropertySignature inside interdependent objects', () => { + it('handles circular readonly PropertySignature inside interdependent objects', () => runTests( 'interface Test1 { readonly [key: string]: Test } interface Test { readonly [key: string]: Test1 }', - ); - }); + )); }); describe('is not readonly', () => { @@ -165,9 +163,8 @@ describe('isTypeReadonly', () => { describe('is not readonly circular', () => { const runTests = runTestIsNotReadonly; - it('handles circular mutable PropertySignature', () => { - runTests('interface Test { [key: string]: Test };'); - }); + it('handles circular mutable PropertySignature', () => + runTests('interface Test { [key: string]: Test };')); it.each([ [ diff --git a/packages/types/tools/copy-ast-spec.ts b/packages/types/tools/copy-ast-spec.ts index f0499a91a4fb..dc2227ae48bc 100644 --- a/packages/types/tools/copy-ast-spec.ts +++ b/packages/types/tools/copy-ast-spec.ts @@ -19,15 +19,9 @@ async function execAsync( stdio: 'inherit', }); - child.on('error', e => { - reject(e); - }); - child.on('exit', () => { - resolve(); - }); - child.on('close', () => { - resolve(); - }); + child.on('error', e => reject(e)); + child.on('exit', () => resolve()); + child.on('close', () => resolve()); }); } diff --git a/packages/typescript-estree/src/create-program/createProjectProgram.ts b/packages/typescript-estree/src/create-program/createProjectProgram.ts index 9996bdf9ba6f..51a2ebdfdfc6 100644 --- a/packages/typescript-estree/src/create-program/createProjectProgram.ts +++ b/packages/typescript-estree/src/create-program/createProjectProgram.ts @@ -38,7 +38,7 @@ function createProjectProgram( // The file was either matched within the tsconfig, or we allow creating a default program // eslint-disable-next-line deprecation/deprecation -- will be cleaned up with the next major - if (astAndProgram ?? parseSettings.DEPRECATED__createDefaultProgram) { + if (astAndProgram || parseSettings.DEPRECATED__createDefaultProgram) { return astAndProgram; } diff --git a/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts b/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts index cd33a9a4aa24..2ec2b4ce35ae 100644 --- a/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts +++ b/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts @@ -146,9 +146,9 @@ function getWatchProgramsForProjects( fileWatchCallbacks && fileWatchCallbacks.size > 0 ) { - fileWatchCallbacks.forEach(cb => { - cb(filePath, ts.FileWatcherEventKind.Changed); - }); + fileWatchCallbacks.forEach(cb => + cb(filePath, ts.FileWatcherEventKind.Changed), + ); } const currentProjectsFromSettings = new Set(parseSettings.projects); @@ -400,9 +400,9 @@ function maybeInvalidateProgram( * We need to make sure typescript knows this so it can update appropriately */ log('tsconfig has changed - triggering program update. %s', tsconfigPath); - fileWatchCallbackTrackingMap.get(tsconfigPath)!.forEach(cb => { - cb(tsconfigPath, ts.FileWatcherEventKind.Changed); - }); + fileWatchCallbackTrackingMap + .get(tsconfigPath)! + .forEach(cb => cb(tsconfigPath, ts.FileWatcherEventKind.Changed)); // tsconfig change means that the file list more than likely changed, so clear the cache programFileListCache.delete(tsconfigPath); @@ -487,9 +487,9 @@ function maybeInvalidateProgram( } log('Marking file as deleted. %s', deletedFile); - fileWatchCallbacks.forEach(cb => { - cb(deletedFile, ts.FileWatcherEventKind.Deleted); - }); + fileWatchCallbacks.forEach(cb => + cb(deletedFile, ts.FileWatcherEventKind.Deleted), + ); // deleted files means that the file list _has_ changed, so clear the cache programFileListCache.delete(tsconfigPath); diff --git a/packages/typescript-estree/src/create-program/useProvidedPrograms.ts b/packages/typescript-estree/src/create-program/useProvidedPrograms.ts index 3eca9eefa5b2..96093e9a3afa 100644 --- a/packages/typescript-estree/src/create-program/useProvidedPrograms.ts +++ b/packages/typescript-estree/src/create-program/useProvidedPrograms.ts @@ -70,7 +70,7 @@ function createProgramFromConfigFile( }, fileExists: fs.existsSync, getCurrentDirectory: () => - (projectDirectory && path.resolve(projectDirectory)) ?? process.cwd(), + (projectDirectory && path.resolve(projectDirectory)) || process.cwd(), readDirectory: ts.sys.readDirectory, readFile: file => fs.readFileSync(file, 'utf-8'), useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames, diff --git a/packages/typescript-estree/src/node-utils.ts b/packages/typescript-estree/src/node-utils.ts index 551a308420cd..74e53c5df21e 100644 --- a/packages/typescript-estree/src/node-utils.ts +++ b/packages/typescript-estree/src/node-utils.ts @@ -363,7 +363,7 @@ export function hasJSXAncestor(node: ts.Node): boolean { export function unescapeStringLiteralText(text: string): string { return text.replace(/&(?:#\d+|#x[\da-fA-F]+|[0-9a-zA-Z]+);/g, entity => { const item = entity.slice(1, -1); - if (item.startsWith('#')) { + if (item[0] === '#') { const codePoint = item[1] === 'x' ? parseInt(item.slice(2), 16) diff --git a/packages/typescript-estree/src/parser.ts b/packages/typescript-estree/src/parser.ts index 833023e75d69..63723c6dd628 100644 --- a/packages/typescript-estree/src/parser.ts +++ b/packages/typescript-estree/src/parser.ts @@ -143,7 +143,7 @@ function parseWithNodeMapsInternal( }; } -let parseAndGenerateServicesCalls: Record = {}; +let parseAndGenerateServicesCalls: { [fileName: string]: number } = {}; // Privately exported utility intended for use in typescript-eslint unit tests only function clearParseAndGenerateServicesCalls(): void { parseAndGenerateServicesCalls = {}; diff --git a/packages/typescript-estree/src/simple-traverse.ts b/packages/typescript-estree/src/simple-traverse.ts index 5590bff21920..67b56d02c380 100644 --- a/packages/typescript-estree/src/simple-traverse.ts +++ b/packages/typescript-estree/src/simple-traverse.ts @@ -24,10 +24,12 @@ type SimpleTraverseOptions = Readonly< } | { visitorKeys?: Readonly; - visitors: Record< - string, - (node: TSESTree.Node, parent: TSESTree.Node | undefined) => void - >; + visitors: { + [key: string]: ( + node: TSESTree.Node, + parent: TSESTree.Node | undefined, + ) => void; + }; } >; diff --git a/packages/typescript-estree/tests/lib/persistentParse.test.ts b/packages/typescript-estree/tests/lib/persistentParse.test.ts index 30bf442af399..63e81d7e260a 100644 --- a/packages/typescript-estree/tests/lib/persistentParse.test.ts +++ b/packages/typescript-estree/tests/lib/persistentParse.test.ts @@ -22,9 +22,7 @@ afterEach(() => { clearWatchCaches(); // clean up the temporary files and folders - tmpDirs.forEach(t => { - t.removeCallback(); - }); + tmpDirs.forEach(t => t.removeCallback()); tmpDirs.clear(); // restore original cwd @@ -91,47 +89,31 @@ function baseTests( it('parses both files successfully when included', () => { const PROJECT_DIR = setup(tsConfigIncludeAll); - expect(() => { - parseFile('foo', PROJECT_DIR); - }).not.toThrow(); - expect(() => { - parseFile('bar', PROJECT_DIR); - }).not.toThrow(); + expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => parseFile('bar', PROJECT_DIR)).not.toThrow(); }); it('parses included files, and throws on excluded files', () => { const PROJECT_DIR = setup(tsConfigExcludeBar); - expect(() => { - parseFile('foo', PROJECT_DIR); - }).not.toThrow(); - expect(() => { - parseFile('bar', PROJECT_DIR); - }).toThrow(); + expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => parseFile('bar', PROJECT_DIR)).toThrow(); }); it('allows parsing of new files', () => { const PROJECT_DIR = setup(tsConfigIncludeAll, false); // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => { - parseFile('foo', PROJECT_DIR); - }).not.toThrow(); + expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); // bar should throw because it doesn't exist yet - expect(() => { - parseFile('bar', PROJECT_DIR); - }).toThrow(); + expect(() => parseFile('bar', PROJECT_DIR)).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, 'bar'); // both files should parse fine now - expect(() => { - parseFile('foo', PROJECT_DIR); - }).not.toThrow(); - expect(() => { - parseFile('bar', PROJECT_DIR); - }).not.toThrow(); + expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => parseFile('bar', PROJECT_DIR)).not.toThrow(); }); it('allows parsing of deeply nested new files', () => { @@ -139,32 +121,22 @@ function baseTests( const bazSlashBar = 'baz/bar' as const; // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => { - parseFile('foo', PROJECT_DIR); - }).not.toThrow(); + expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); // bar should throw because it doesn't exist yet - expect(() => { - parseFile(bazSlashBar, PROJECT_DIR); - }).toThrow(); + expect(() => parseFile(bazSlashBar, PROJECT_DIR)).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, bazSlashBar); // both files should parse fine now - expect(() => { - parseFile('foo', PROJECT_DIR); - }).not.toThrow(); - expect(() => { - parseFile(bazSlashBar, PROJECT_DIR); - }).not.toThrow(); + expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => parseFile(bazSlashBar, PROJECT_DIR)).not.toThrow(); }); it('allows parsing of deeply nested new files in new folder', () => { const PROJECT_DIR = setup(tsConfigIncludeAll); - expect(() => { - parseFile('foo', PROJECT_DIR); - }).not.toThrow(); + expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); // Create deep folder structure after first parse (this is important step) // context: https://github.com/typescript-eslint/typescript-eslint/issues/1394 @@ -176,9 +148,7 @@ function baseTests( // write a new file and attempt to parse it writeFile(PROJECT_DIR, bazSlashBar); - expect(() => { - parseFile(bazSlashBar, PROJECT_DIR); - }).not.toThrow(); + expect(() => parseFile(bazSlashBar, PROJECT_DIR)).not.toThrow(); }); it('allows renaming of files', () => { @@ -186,59 +156,39 @@ function baseTests( const bazSlashBar = 'baz/bar' as const; // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => { - parseFile('foo', PROJECT_DIR); - }).not.toThrow(); + expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); // bar should throw because it doesn't exist yet - expect(() => { - parseFile(bazSlashBar, PROJECT_DIR); - }).toThrow(); + expect(() => parseFile(bazSlashBar, PROJECT_DIR)).toThrow(); // write a new file and attempt to parse it renameFile(PROJECT_DIR, 'bar', bazSlashBar); // both files should parse fine now - expect(() => { - parseFile('foo', PROJECT_DIR); - }).not.toThrow(); - expect(() => { - parseFile(bazSlashBar, PROJECT_DIR); - }).not.toThrow(); + expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => parseFile(bazSlashBar, PROJECT_DIR)).not.toThrow(); }); it('reacts to changes in the tsconfig', () => { const PROJECT_DIR = setup(tsConfigExcludeBar); // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => { - parseFile('foo', PROJECT_DIR); - }).not.toThrow(); - expect(() => { - parseFile('bar', PROJECT_DIR); - }).toThrow(); + expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => parseFile('bar', PROJECT_DIR)).toThrow(); // change the config file so it now includes all files writeTSConfig(PROJECT_DIR, tsConfigIncludeAll); - expect(() => { - parseFile('foo', PROJECT_DIR); - }).not.toThrow(); - expect(() => { - parseFile('bar', PROJECT_DIR); - }).not.toThrow(); + expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => parseFile('bar', PROJECT_DIR)).not.toThrow(); }); it('should work with relative paths', () => { const PROJECT_DIR = setup(tsConfigIncludeAll, false); // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => { - parseFile('foo', PROJECT_DIR, true); - }).not.toThrow(); + expect(() => parseFile('foo', PROJECT_DIR, true)).not.toThrow(); // bar should throw because it doesn't exist yet - expect(() => { - parseFile('bar', PROJECT_DIR, true); - }).toThrow(); + expect(() => parseFile('bar', PROJECT_DIR, true)).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, 'bar'); @@ -247,12 +197,8 @@ function baseTests( expect(existsSync('bar', PROJECT_DIR)).toBe(true); // both files should parse fine now - expect(() => { - parseFile('foo', PROJECT_DIR, true); - }).not.toThrow(); - expect(() => { - parseFile('bar', PROJECT_DIR, true); - }).not.toThrow(); + expect(() => parseFile('foo', PROJECT_DIR, true)).not.toThrow(); + expect(() => parseFile('bar', PROJECT_DIR, true)).not.toThrow(); }); it('should work with relative paths without tsconfig root', () => { @@ -260,13 +206,9 @@ function baseTests( process.chdir(PROJECT_DIR); // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => { - parseFile('foo', PROJECT_DIR, true, true); - }).not.toThrow(); + expect(() => parseFile('foo', PROJECT_DIR, true, true)).not.toThrow(); // bar should throw because it doesn't exist yet - expect(() => { - parseFile('bar', PROJECT_DIR, true, true); - }).toThrow(); + expect(() => parseFile('bar', PROJECT_DIR, true, true)).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, 'bar'); @@ -276,12 +218,8 @@ function baseTests( expect(existsSync('bar', PROJECT_DIR)).toBe(true); // both files should parse fine now - expect(() => { - parseFile('foo', PROJECT_DIR, true, true); - }).not.toThrow(); - expect(() => { - parseFile('bar', PROJECT_DIR, true, true); - }).not.toThrow(); + expect(() => parseFile('foo', PROJECT_DIR, true, true)).not.toThrow(); + expect(() => parseFile('bar', PROJECT_DIR, true, true)).not.toThrow(); }); } @@ -331,22 +269,14 @@ describe('persistent parse', () => { const PROJECT_DIR = setup({}, false); // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => { - parseFile('foo', PROJECT_DIR); - }).not.toThrow(); - expect(() => { - parseFile('bar', PROJECT_DIR); - }).toThrow(); + expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => parseFile('bar', PROJECT_DIR)).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, 'bar'); - expect(() => { - parseFile('foo', PROJECT_DIR); - }).not.toThrow(); - expect(() => { - parseFile('bar', PROJECT_DIR); - }).not.toThrow(); + expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => parseFile('bar', PROJECT_DIR)).not.toThrow(); }); it('handles tsconfigs with no includes/excludes (nested)', () => { @@ -354,22 +284,14 @@ describe('persistent parse', () => { const bazSlashBar = 'baz/bar' as const; // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => { - parseFile('foo', PROJECT_DIR); - }).not.toThrow(); - expect(() => { - parseFile(bazSlashBar, PROJECT_DIR); - }).toThrow(); + expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => parseFile(bazSlashBar, PROJECT_DIR)).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, bazSlashBar); - expect(() => { - parseFile('foo', PROJECT_DIR); - }).not.toThrow(); - expect(() => { - parseFile(bazSlashBar, PROJECT_DIR); - }).not.toThrow(); + expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => parseFile(bazSlashBar, PROJECT_DIR)).not.toThrow(); }); }); @@ -412,9 +334,7 @@ describe('persistent parse', () => { it(`first parse of ${name} should not throw`, () => { const PROJECT_DIR = setup(tsConfigIncludeAll); writeFile(PROJECT_DIR, name); - expect(() => { - parseFile(name, PROJECT_DIR); - }).not.toThrow(); + expect(() => parseFile(name, PROJECT_DIR)).not.toThrow(); }); } }); diff --git a/packages/typescript-estree/tests/lib/semanticInfo.test.ts b/packages/typescript-estree/tests/lib/semanticInfo.test.ts index 8dc9cfda9ecd..6c50712e0eae 100644 --- a/packages/typescript-estree/tests/lib/semanticInfo.test.ts +++ b/packages/typescript-estree/tests/lib/semanticInfo.test.ts @@ -37,9 +37,7 @@ function createOptions(fileName: string): TSESTreeOptions & { cwd?: string } { } // ensure tsconfig-parser watch caches are clean for each test -beforeEach(() => { - clearWatchCaches(); -}); +beforeEach(() => clearWatchCaches()); describe('semanticInfo', () => { // test all AST snapshots diff --git a/packages/utils/src/json-schema.ts b/packages/utils/src/json-schema.ts index 4a09a589ad20..b641637745ae 100644 --- a/packages/utils/src/json-schema.ts +++ b/packages/utils/src/json-schema.ts @@ -106,11 +106,19 @@ interface JSONSchema4Base { /** * Reusable definitions that can be referenced via `$ref` */ - definitions?: Record | undefined; + definitions?: + | { + [k: string]: JSONSchema4; + } + | undefined; /** * Reusable definitions that can be referenced via `$ref` */ - $defs?: Record | undefined; + $defs?: + | { + [k: string]: JSONSchema4; + } + | undefined; /** * The value of this property MUST be another schema which will provide @@ -234,7 +242,11 @@ export interface JSONSchema4ObjectSchema extends JSONSchema4Base { * * @see https://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.2 */ - properties?: Record | undefined; + properties?: + | { + [k: string]: JSONSchema4; + } + | undefined; /** * This attribute is an object that defines the schema for a set of @@ -247,14 +259,22 @@ export interface JSONSchema4ObjectSchema extends JSONSchema4Base { * * @see https://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.3 */ - patternProperties?: Record | undefined; + patternProperties?: + | { + [k: string]: JSONSchema4; + } + | undefined; /** * The `dependencies` keyword conditionally applies a sub-schema when a given * property is present. This schema is applied in the same way `allOf` applies * schemas. Nothing is merged or extended. Both schemas apply independently. */ - dependencies?: Record | undefined; + dependencies?: + | { + [k: string]: JSONSchema4 | string[]; + } + | undefined; /** * The maximum number of properties allowed for record-style schemas diff --git a/packages/utils/src/ts-eslint/CLIEngine.ts b/packages/utils/src/ts-eslint/CLIEngine.ts index ccd785dc5f5c..15a58754ec93 100644 --- a/packages/utils/src/ts-eslint/CLIEngine.ts +++ b/packages/utils/src/ts-eslint/CLIEngine.ts @@ -106,7 +106,7 @@ declare class CLIEngineBase { namespace CLIEngine { export interface Options { allowInlineConfig?: boolean; - baseConfig?: Record | false; + baseConfig?: false | { [name: string]: unknown }; cache?: boolean; cacheFile?: string; cacheLocation?: string; @@ -125,7 +125,9 @@ namespace CLIEngine { parserOptions?: Linter.ParserOptions; plugins?: string[]; resolvePluginsRelativeTo?: string; - rules?: Record; + rules?: { + [name: string]: Linter.RuleLevel | Linter.RuleLevelAndOptions; + }; rulePaths?: string[]; reportUnusedDisableDirectives?: boolean; } @@ -156,7 +158,9 @@ namespace CLIEngine { } export interface LintResultData { - rulesMeta: Record>; + rulesMeta: { + [ruleId: string]: RuleMetaData; + }; } export type Formatter = ( diff --git a/packages/utils/src/ts-eslint/Linter.ts b/packages/utils/src/ts-eslint/Linter.ts index 62a6645e0091..59274a7e6fc4 100644 --- a/packages/utils/src/ts-eslint/Linter.ts +++ b/packages/utils/src/ts-eslint/Linter.ts @@ -130,8 +130,12 @@ namespace Linter { export type GlobalVariableOptionBase = 'off' | 'readonly' | 'writable'; export type GlobalVariableOption = GlobalVariableOptionBase | boolean; - export type GlobalsConfig = Record; - export type EnvironmentConfig = Record; + export interface GlobalsConfig { + [name: string]: GlobalVariableOption; + } + export interface EnvironmentConfig { + [name: string]: boolean; + } // https://github.com/eslint/eslint/blob/v6.8.0/conf/config-schema.js interface BaseConfig { diff --git a/packages/utils/src/ts-eslint/Rule.ts b/packages/utils/src/ts-eslint/Rule.ts index 87309acb568b..4ff0546bb65c 100644 --- a/packages/utils/src/ts-eslint/Rule.ts +++ b/packages/utils/src/ts-eslint/Rule.ts @@ -170,7 +170,6 @@ type ReportDescriptor = * Plugins can add their settings using declaration * merging against this interface. */ -// eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style interface SharedConfigurationSettings { [name: string]: unknown; } @@ -429,7 +428,9 @@ interface RuleListenerBaseSelectors { type RuleListenerExitSelectors = { [K in keyof RuleListenerBaseSelectors as `${K}:exit`]: RuleListenerBaseSelectors[K]; }; -type RuleListenerCatchAllBaseCase = Record; +interface RuleListenerCatchAllBaseCase { + [nodeSelector: string]: RuleFunction | undefined; +} // Interface to merge into for anyone that wants to add more selectors // eslint-disable-next-line @typescript-eslint/no-empty-interface interface RuleListenerExtension {} diff --git a/packages/utils/src/ts-eslint/SourceCode.ts b/packages/utils/src/ts-eslint/SourceCode.ts index 7e8352b13d9d..3d7f33dd93c2 100644 --- a/packages/utils/src/ts-eslint/SourceCode.ts +++ b/packages/utils/src/ts-eslint/SourceCode.ts @@ -384,7 +384,9 @@ namespace SourceCode { visitorKeys: VisitorKeys | null; } - export type VisitorKeys = Record; + export interface VisitorKeys { + [nodeType: string]: string[]; + } export type FilterPredicate = (token: TSESTree.Token) => boolean; export type GetFilterPredicate = diff --git a/packages/utils/tests/eslint-utils/nullThrows.test.ts b/packages/utils/tests/eslint-utils/nullThrows.test.ts index b213b3900bf5..7997fecaa6df 100644 --- a/packages/utils/tests/eslint-utils/nullThrows.test.ts +++ b/packages/utils/tests/eslint-utils/nullThrows.test.ts @@ -24,8 +24,8 @@ describe('nullThrows', () => { }); it('throws an error when the value is undefined', () => { - expect(() => { - nullThrows(undefined, NullThrowsReasons.MissingParent); - }).toThrow(NullThrowsReasons.MissingParent); + expect(() => + nullThrows(undefined, NullThrowsReasons.MissingParent), + ).toThrow(NullThrowsReasons.MissingParent); }); }); diff --git a/packages/visitor-keys/src/visitor-keys.ts b/packages/visitor-keys/src/visitor-keys.ts index f4d61fd6230d..eaff7e7ccc26 100644 --- a/packages/visitor-keys/src/visitor-keys.ts +++ b/packages/visitor-keys/src/visitor-keys.ts @@ -1,7 +1,9 @@ import type { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/types'; import * as eslintVisitorKeys from 'eslint-visitor-keys'; -type VisitorKeys = Readonly>; +interface VisitorKeys { + readonly [type: string]: readonly string[] | undefined; +} type GetNodeTypeKeys = Exclude< keyof Extract, diff --git a/packages/website/src/components/OptionsSelector.tsx b/packages/website/src/components/OptionsSelector.tsx index 95f491c0112b..5ab5421be966 100644 --- a/packages/website/src/components/OptionsSelector.tsx +++ b/packages/website/src/components/OptionsSelector.tsx @@ -55,9 +55,7 @@ function OptionsSelectorContent({ className="text--right" value={state.ts} disabled={!tsVersions.length} - onChange={(ts): void => { - setState({ ts }); - }} + onChange={(ts): void => setState({ ts })} options={(tsVersions.length && tsVersions) || [state.ts]} /> @@ -69,9 +67,7 @@ function OptionsSelectorContent({ { - setState({ fileType }); - }} + onChange={(fileType): void => setState({ fileType })} options={fileTypes} /> @@ -79,9 +75,7 @@ function OptionsSelectorContent({ { - setState({ sourceType }); - }} + onChange={(sourceType): void => setState({ sourceType })} options={['script', 'module']} /> @@ -89,18 +83,14 @@ function OptionsSelectorContent({ { - setState({ scroll }); - }} + onChange={(scroll): void => setState({ scroll })} /> { - setState({ showTokens }); - }} + onChange={(showTokens): void => setState({ showTokens })} /> diff --git a/packages/website/src/components/Playground.tsx b/packages/website/src/components/Playground.tsx index c443dc66277d..d0e9be8a31c7 100644 --- a/packages/website/src/components/Playground.tsx +++ b/packages/website/src/components/Playground.tsx @@ -152,9 +152,7 @@ function Playground(): JSX.Element { { - setState({ showAST: v }); - }} + change={(v): void => setState({ showAST: v })} /> {state.showAST === 'es' && ( void; mode: FilterMode; }): JSX.Element { - const toNextMode = (): void => { + const toNextMode = (): void => setMode(filterModes[(filterModes.indexOf(mode) + 1) % filterModes.length]); - }; return (
  • diff --git a/packages/website/src/components/lib/createEventsBinder.ts b/packages/website/src/components/lib/createEventsBinder.ts index 47cc37fd3d17..6b5bfaecbee1 100644 --- a/packages/website/src/components/lib/createEventsBinder.ts +++ b/packages/website/src/components/lib/createEventsBinder.ts @@ -7,9 +7,7 @@ export function createEventsBinder void>(): { return { trigger(...args: Parameters): void { - events.forEach(cb => { - cb(...args); - }); + events.forEach(cb => cb(...args)); }, register(cb: T): () => void { events.add(cb); diff --git a/packages/website/src/components/linter/bridge.ts b/packages/website/src/components/linter/bridge.ts index 03ffb58e33aa..4a4d52e44637 100644 --- a/packages/website/src/components/linter/bridge.ts +++ b/packages/website/src/components/linter/bridge.ts @@ -48,9 +48,7 @@ export function createFileSystem( ): void => { fileWatcherCallbacks.forEach((callbacks, key) => { if (key.test(path)) { - callbacks.forEach(cb => { - cb(path, type); - }); + callbacks.forEach(cb => cb(path, type)); } }); }; diff --git a/packages/website/src/hooks/useBool.ts b/packages/website/src/hooks/useBool.ts index c4e6c569e8da..b06c9c40e5a4 100644 --- a/packages/website/src/hooks/useBool.ts +++ b/packages/website/src/hooks/useBool.ts @@ -6,9 +6,10 @@ export function useBool( ): [boolean, () => void, Dispatch>] { const [value, setValue] = useState(initialState); - const toggle = useCallback((): void => { - setValue(currentValue => !currentValue); - }, []); + const toggle = useCallback( + (): void => setValue(currentValue => !currentValue), + [], + ); return [value, toggle, setValue]; } diff --git a/packages/website/src/hooks/useMediaQuery.ts b/packages/website/src/hooks/useMediaQuery.ts index 964797e20ddd..1bd928c4a4b2 100644 --- a/packages/website/src/hooks/useMediaQuery.ts +++ b/packages/website/src/hooks/useMediaQuery.ts @@ -17,9 +17,8 @@ const useMediaQuery = (mediaQuery: string): boolean => { useEffect(() => { const mediaQueryList = window.matchMedia(mediaQuery); - const documentChangeHandler = (): void => { + const documentChangeHandler = (): void => setIsVerified(!!mediaQueryList.matches); - }; try { mediaQueryList.addEventListener('change', documentChangeHandler); diff --git a/packages/website/src/theme/CodeBlock/Content/String.tsx b/packages/website/src/theme/CodeBlock/Content/String.tsx index 94fe5b84db61..46ba5682c281 100644 --- a/packages/website/src/theme/CodeBlock/Content/String.tsx +++ b/packages/website/src/theme/CodeBlock/Content/String.tsx @@ -107,9 +107,7 @@ export default function CodeBlockString({ {(wordWrap.isEnabled || wordWrap.isCodeScrollable) && ( { - wordWrap.toggle(); - }} + onClick={(): void => wordWrap.toggle()} isEnabled={wordWrap.isEnabled} /> )} From 335925c234cd0e737ae963f86f2769bd2815cce0 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Mon, 26 Jun 2023 15:33:08 -0700 Subject: [PATCH 3/6] Updated snapshots --- .../snapshots/1-Babel-Error.shot | 3 +++ .../snapshots/2-Alignment-Error.shot | 3 +++ .../snapshots/1-Babel-Error.shot | 3 +++ .../snapshots/2-Alignment-Error.shot | 3 +++ .../snapshots/1-Babel-Error.shot | 3 +++ .../snapshots/2-Alignment-Error.shot | 3 +++ .../snapshots/1-Babel-Error.shot | 3 +++ .../snapshots/2-Alignment-Error.shot | 3 +++ .../snapshots/1-Babel-Error.shot | 3 +++ .../snapshots/2-Alignment-Error.shot | 3 +++ .../_error_/with-member/snapshots/1-Babel-Error.shot | 3 +++ .../with-member/snapshots/2-Alignment-Error.shot | 3 +++ .../tests/lib/__snapshots__/convert.test.ts.snap | 10 +++++----- 13 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-abstract-accessor-with-value/snapshots/1-Babel-Error.shot create mode 100644 packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-abstract-accessor-with-value/snapshots/2-Alignment-Error.shot create mode 100644 packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-abstract-property-with-value/snapshots/1-Babel-Error.shot create mode 100644 packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-abstract-property-with-value/snapshots/2-Alignment-Error.shot create mode 100644 packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/override-function-parameter/snapshots/1-Babel-Error.shot create mode 100644 packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/override-function-parameter/snapshots/2-Alignment-Error.shot create mode 100644 packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/override-method-parameter/snapshots/1-Babel-Error.shot create mode 100644 packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/override-method-parameter/snapshots/2-Alignment-Error.shot create mode 100644 packages/ast-spec/src/type/TSMappedType/fixtures/_error_/looks-like-mapped-type-but-with-members/snapshots/1-Babel-Error.shot create mode 100644 packages/ast-spec/src/type/TSMappedType/fixtures/_error_/looks-like-mapped-type-but-with-members/snapshots/2-Alignment-Error.shot create mode 100644 packages/ast-spec/src/type/TSMappedType/fixtures/_error_/with-member/snapshots/1-Babel-Error.shot create mode 100644 packages/ast-spec/src/type/TSMappedType/fixtures/_error_/with-member/snapshots/2-Alignment-Error.shot diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-abstract-accessor-with-value/snapshots/1-Babel-Error.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-abstract-accessor-with-value/snapshots/1-Babel-Error.shot new file mode 100644 index 000000000000..f314b35255b9 --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-abstract-accessor-with-value/snapshots/1-Babel-Error.shot @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty _error_ modifier-abstract-accessor-with-value Babel - Error 1`] = `"NO ERROR"`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-abstract-accessor-with-value/snapshots/2-Alignment-Error.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-abstract-accessor-with-value/snapshots/2-Alignment-Error.shot new file mode 100644 index 000000000000..4e826d92c94c --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-abstract-accessor-with-value/snapshots/2-Alignment-Error.shot @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty _error_ modifier-abstract-accessor-with-value Error Alignment 1`] = `"No errors"`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-abstract-property-with-value/snapshots/1-Babel-Error.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-abstract-property-with-value/snapshots/1-Babel-Error.shot new file mode 100644 index 000000000000..24fbc9009898 --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-abstract-property-with-value/snapshots/1-Babel-Error.shot @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty _error_ modifier-abstract-property-with-value Babel - Error 1`] = `[SyntaxError: Property 'property' cannot have an initializer because it is marked abstract. (2:20)]`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-abstract-property-with-value/snapshots/2-Alignment-Error.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-abstract-property-with-value/snapshots/2-Alignment-Error.shot new file mode 100644 index 000000000000..7e77cd5d46e8 --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-abstract-property-with-value/snapshots/2-Alignment-Error.shot @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty _error_ modifier-abstract-property-with-value Error Alignment 1`] = `"Babel errored but TSESTree didn't"`; diff --git a/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/override-function-parameter/snapshots/1-Babel-Error.shot b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/override-function-parameter/snapshots/1-Babel-Error.shot new file mode 100644 index 000000000000..10b3877c585a --- /dev/null +++ b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/override-function-parameter/snapshots/1-Babel-Error.shot @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures parameter TSParameterProperty _error_ override-function-parameter Babel - Error 1`] = `[SyntaxError: A parameter property is only allowed in a constructor implementation. (1:13)]`; diff --git a/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/override-function-parameter/snapshots/2-Alignment-Error.shot b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/override-function-parameter/snapshots/2-Alignment-Error.shot new file mode 100644 index 000000000000..fdd638615229 --- /dev/null +++ b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/override-function-parameter/snapshots/2-Alignment-Error.shot @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures parameter TSParameterProperty _error_ override-function-parameter Error Alignment 1`] = `"Babel errored but TSESTree didn't"`; diff --git a/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/override-method-parameter/snapshots/1-Babel-Error.shot b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/override-method-parameter/snapshots/1-Babel-Error.shot new file mode 100644 index 000000000000..63ae30ee6f59 --- /dev/null +++ b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/override-method-parameter/snapshots/1-Babel-Error.shot @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures parameter TSParameterProperty _error_ override-method-parameter Babel - Error 1`] = `[SyntaxError: A parameter property is only allowed in a constructor implementation. (2:9)]`; diff --git a/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/override-method-parameter/snapshots/2-Alignment-Error.shot b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/override-method-parameter/snapshots/2-Alignment-Error.shot new file mode 100644 index 000000000000..500c7d90879c --- /dev/null +++ b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/override-method-parameter/snapshots/2-Alignment-Error.shot @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures parameter TSParameterProperty _error_ override-method-parameter Error Alignment 1`] = `"Babel errored but TSESTree didn't"`; diff --git a/packages/ast-spec/src/type/TSMappedType/fixtures/_error_/looks-like-mapped-type-but-with-members/snapshots/1-Babel-Error.shot b/packages/ast-spec/src/type/TSMappedType/fixtures/_error_/looks-like-mapped-type-but-with-members/snapshots/1-Babel-Error.shot new file mode 100644 index 000000000000..a18ec232c74e --- /dev/null +++ b/packages/ast-spec/src/type/TSMappedType/fixtures/_error_/looks-like-mapped-type-but-with-members/snapshots/1-Babel-Error.shot @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures type TSMappedType _error_ looks-like-mapped-type-but-with-members Babel - Error 1`] = `[SyntaxError: Unexpected token, expected "]" (3:16)]`; diff --git a/packages/ast-spec/src/type/TSMappedType/fixtures/_error_/looks-like-mapped-type-but-with-members/snapshots/2-Alignment-Error.shot b/packages/ast-spec/src/type/TSMappedType/fixtures/_error_/looks-like-mapped-type-but-with-members/snapshots/2-Alignment-Error.shot new file mode 100644 index 000000000000..be7ee0f9c846 --- /dev/null +++ b/packages/ast-spec/src/type/TSMappedType/fixtures/_error_/looks-like-mapped-type-but-with-members/snapshots/2-Alignment-Error.shot @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures type TSMappedType _error_ looks-like-mapped-type-but-with-members Error Alignment 1`] = `"Both errored"`; diff --git a/packages/ast-spec/src/type/TSMappedType/fixtures/_error_/with-member/snapshots/1-Babel-Error.shot b/packages/ast-spec/src/type/TSMappedType/fixtures/_error_/with-member/snapshots/1-Babel-Error.shot new file mode 100644 index 000000000000..bfe056cd7872 --- /dev/null +++ b/packages/ast-spec/src/type/TSMappedType/fixtures/_error_/with-member/snapshots/1-Babel-Error.shot @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures type TSMappedType _error_ with-member Babel - Error 1`] = `[SyntaxError: Unexpected token, expected "}" (3:2)]`; diff --git a/packages/ast-spec/src/type/TSMappedType/fixtures/_error_/with-member/snapshots/2-Alignment-Error.shot b/packages/ast-spec/src/type/TSMappedType/fixtures/_error_/with-member/snapshots/2-Alignment-Error.shot new file mode 100644 index 000000000000..42d0ee954c56 --- /dev/null +++ b/packages/ast-spec/src/type/TSMappedType/fixtures/_error_/with-member/snapshots/2-Alignment-Error.shot @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures type TSMappedType _error_ with-member Error Alignment 1`] = `"Babel errored but TSESTree didn't"`; diff --git a/packages/typescript-estree/tests/lib/__snapshots__/convert.test.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/convert.test.ts.snap index 0a1c9eb2ace9..87fef5110321 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/convert.test.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/convert.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`convert deeplyCopy should convert array of nodes 1`] = ` +exports[`convert deeplyCopy deeplyCopy should convert array of nodes 1`] = ` { "ambientModuleNames": undefined, "amdDependencies": [], @@ -195,7 +195,7 @@ exports[`convert deeplyCopy should convert array of nodes 1`] = ` } `; -exports[`convert deeplyCopy should convert node correctly 1`] = ` +exports[`convert deeplyCopy deeplyCopy should convert node correctly 1`] = ` { "body": [ { @@ -258,7 +258,7 @@ exports[`convert deeplyCopy should convert node correctly 1`] = ` } `; -exports[`convert deeplyCopy should convert node with decorators correctly 1`] = ` +exports[`convert deeplyCopy deeplyCopy should convert node with decorators correctly 1`] = ` { "decorators": [ { @@ -341,7 +341,7 @@ exports[`convert deeplyCopy should convert node with decorators correctly 1`] = } `; -exports[`convert deeplyCopy should convert node with type arguments correctly 1`] = ` +exports[`convert deeplyCopy deeplyCopy should convert node with type arguments correctly 1`] = ` { "arguments": [], "expression": { @@ -441,7 +441,7 @@ exports[`convert deeplyCopy should convert node with type arguments correctly 1` } `; -exports[`convert deeplyCopy should convert node with type parameters correctly 1`] = ` +exports[`convert deeplyCopy deeplyCopy should convert node with type parameters correctly 1`] = ` { "loc": { "end": { From 9825cb00549b82812fc9dabee3c2c85c7e87b3c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josh=20Goldberg=20=E2=9C=A8?= Date: Fri, 30 Jun 2023 16:22:42 -0700 Subject: [PATCH 4/6] Update packages/typescript-estree/tests/lib/convert.test.ts Co-authored-by: rubiesonthesky <2591240+rubiesonthesky@users.noreply.github.com> --- packages/typescript-estree/tests/lib/convert.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/typescript-estree/tests/lib/convert.test.ts b/packages/typescript-estree/tests/lib/convert.test.ts index 97b22624acac..829da9ce659f 100644 --- a/packages/typescript-estree/tests/lib/convert.test.ts +++ b/packages/typescript-estree/tests/lib/convert.test.ts @@ -23,7 +23,7 @@ describe('convert', () => { /* eslint-disable @typescript-eslint/dot-notation */ describe('deeplyCopy', () => { - it('deeplyCopy should convert node correctly', () => { + it('should convert node correctly', () => { const ast = convertCode('type foo = ?foo | ?(() => void)?'); function fakeUnknownKind(node: ts.Node): void { From a8fb72f9d1c624747c5fc4e31983358c0e7039c5 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Fri, 30 Jun 2023 16:23:02 -0700 Subject: [PATCH 5/6] More deeplyCopy removals --- packages/typescript-estree/tests/lib/convert.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/typescript-estree/tests/lib/convert.test.ts b/packages/typescript-estree/tests/lib/convert.test.ts index 829da9ce659f..9988c969b6a7 100644 --- a/packages/typescript-estree/tests/lib/convert.test.ts +++ b/packages/typescript-estree/tests/lib/convert.test.ts @@ -39,7 +39,7 @@ describe('convert', () => { expect(instance.convertProgram()).toMatchSnapshot(); }); - it('deeplyCopy should convert node with decorators correctly', () => { + it('should convert node with decorators correctly', () => { const ast = convertCode('@test class foo {}'); const instance = new Converter(ast); @@ -49,7 +49,7 @@ describe('convert', () => { ).toMatchSnapshot(); }); - it('deeplyCopy should convert node with type parameters correctly', () => { + it('should convert node with type parameters correctly', () => { const ast = convertCode('class foo {}'); const instance = new Converter(ast); @@ -59,7 +59,7 @@ describe('convert', () => { ).toMatchSnapshot(); }); - it('deeplyCopy should convert node with type arguments correctly', () => { + it('should convert node with type arguments correctly', () => { const ast = convertCode('new foo()'); const instance = new Converter(ast); @@ -72,14 +72,14 @@ describe('convert', () => { ).toMatchSnapshot(); }); - it('deeplyCopy should convert array of nodes', () => { + it('should convert array of nodes', () => { const ast = convertCode('new foo()'); const instance = new Converter(ast); expect(instance['deeplyCopy'](ast)).toMatchSnapshot(); }); - it('deeplyCopy should fail on unknown node', () => { + it('should fail on unknown node', () => { const ast = convertCode('type foo = ?foo | ?(() => void)?'); const instance = new Converter(ast, { From bc9238e376cad082a10683304a847ede46d5fe76 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Fri, 30 Jun 2023 16:23:59 -0700 Subject: [PATCH 6/6] Updated test snapshots --- .../tests/lib/__snapshots__/convert.test.ts.snap | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/typescript-estree/tests/lib/__snapshots__/convert.test.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/convert.test.ts.snap index 87fef5110321..0a1c9eb2ace9 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/convert.test.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/convert.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`convert deeplyCopy deeplyCopy should convert array of nodes 1`] = ` +exports[`convert deeplyCopy should convert array of nodes 1`] = ` { "ambientModuleNames": undefined, "amdDependencies": [], @@ -195,7 +195,7 @@ exports[`convert deeplyCopy deeplyCopy should convert array of nodes 1`] = ` } `; -exports[`convert deeplyCopy deeplyCopy should convert node correctly 1`] = ` +exports[`convert deeplyCopy should convert node correctly 1`] = ` { "body": [ { @@ -258,7 +258,7 @@ exports[`convert deeplyCopy deeplyCopy should convert node correctly 1`] = ` } `; -exports[`convert deeplyCopy deeplyCopy should convert node with decorators correctly 1`] = ` +exports[`convert deeplyCopy should convert node with decorators correctly 1`] = ` { "decorators": [ { @@ -341,7 +341,7 @@ exports[`convert deeplyCopy deeplyCopy should convert node with decorators corre } `; -exports[`convert deeplyCopy deeplyCopy should convert node with type arguments correctly 1`] = ` +exports[`convert deeplyCopy should convert node with type arguments correctly 1`] = ` { "arguments": [], "expression": { @@ -441,7 +441,7 @@ exports[`convert deeplyCopy deeplyCopy should convert node with type arguments c } `; -exports[`convert deeplyCopy deeplyCopy should convert node with type parameters correctly 1`] = ` +exports[`convert deeplyCopy should convert node with type parameters correctly 1`] = ` { "loc": { "end": {