diff --git a/.eslintrc.js b/.eslintrc.js index f6502ce3c885..9795cfb5792d 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,18 @@ module.exports = { // make sure we're not leveraging any deprecated APIs 'deprecation/deprecation': 'error', + // 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 // - '@typescript-eslint/array-type': 'error', '@typescript-eslint/ban-ts-comment': [ 'error', { @@ -67,7 +75,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 +83,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 +97,6 @@ module.exports = { allowRegExp: true, }, ], - '@typescript-eslint/sort-type-constituents': 'error', '@typescript-eslint/no-unused-vars': [ 'error', { varsIgnorePattern: '^_', argsIgnorePattern: '^_' }, @@ -238,6 +236,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/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/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/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-restricted-imports.ts b/packages/eslint-plugin/src/rules/no-restricted-imports.ts index 17e93f7febaa..8c191dbaae9c 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' && 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/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/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/scope-manager/src/scope/ScopeBase.ts b/packages/scope-manager/src/scope/ScopeBase.ts index e107c7d90570..81c712dff389 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 = @@ -386,7 +386,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/tests/eslint-scope/es6-destructuring-assignments.test.ts b/packages/scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts index 14cfeceb368d..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, 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..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, 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/getWatchProgramsForProjects.ts b/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts index 01ab04c3ae56..2ec2b4ce35ae 100644 --- a/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts +++ b/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts @@ -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; 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..63723c6dd628 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) & 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..9988c969b6a7 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('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('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('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('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('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('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/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/ts-eslint/Rule.ts b/packages/utils/src/ts-eslint/Rule.ts index 16d34a67fc2a..4ff0546bb65c 100644 --- a/packages/utils/src/ts-eslint/Rule.ts +++ b/packages/utils/src/ts-eslint/Rule.ts @@ -432,6 +432,7 @@ 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 {} type RuleListener = RuleListenerBaseSelectors &