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": { pFad - Phonifier reborn

    Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

    Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


    Alternative Proxies:

    Alternative Proxy

    pFad Proxy

    pFad v3 Proxy

    pFad v4 Proxy