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..1d07e54351b4 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 @@ -11,11 +11,6 @@ This rule simply warns against using them, as using them will likely introduce t */ const BANNED_PROPERTIES = [ - // { - // type: 'Node', - // property: 'parent', - // fixWith: null, - // }, { type: 'Symbol', property: 'declarations', @@ -87,10 +82,6 @@ export default createRule({ messageId: 'suggestedFix', data: banned, fix(fixer): TSESLint.RuleFix | null { - if (banned.fixWith == null) { - return null; - } - return fixer.replaceText(node.property, banned.fixWith); }, }, 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..9e97e44d2536 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 @@ -40,8 +40,8 @@ export default createRule({ return { Literal(node: TSESTree.Literal): void { if ( - node.parent?.type === AST_NODE_TYPES.TSEnumMember && - node.parent.parent?.type === AST_NODE_TYPES.TSEnumDeclaration && + node.parent.type === AST_NODE_TYPES.TSEnumMember && + node.parent.parent.type === AST_NODE_TYPES.TSEnumDeclaration && ['AST_NODE_TYPES', 'AST_TOKEN_TYPES', 'DefinitionType'].includes( node.parent.parent.id.name, ) diff --git a/packages/eslint-plugin-tslint/src/rules/config.ts b/packages/eslint-plugin-tslint/src/rules/config.ts index 23b7558b80fb..2cb602917688 100644 --- a/packages/eslint-plugin-tslint/src/rules/config.ts +++ b/packages/eslint-plugin-tslint/src/rules/config.ts @@ -146,7 +146,7 @@ export default createRule({ /** * Format the TSLint results for ESLint */ - if (result.failures?.length) { + if (result.failures.length) { result.failures.forEach(failure => { const start = failure.getStartPosition().getLineAndCharacter(); const end = failure.getEndPosition().getLineAndCharacter(); diff --git a/packages/eslint-plugin/src/rules/no-misused-promises.ts b/packages/eslint-plugin/src/rules/no-misused-promises.ts index 7fd6fb9ca71c..fa5f9ae5796b 100644 --- a/packages/eslint-plugin/src/rules/no-misused-promises.ts +++ b/packages/eslint-plugin/src/rules/no-misused-promises.ts @@ -3,7 +3,7 @@ import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; -import { createRule, getParserServices, getTypeArguments } from '../util'; +import { createRule, getParserServices } from '../util'; type Options = [ { @@ -556,7 +556,7 @@ function voidFunctionArguments( // Unwrap 'Array' to 'MaybeVoidFunction', // so that we'll handle it in the same way as a non-rest // 'param: MaybeVoidFunction' - type = getTypeArguments(type, checker)[0]; + type = checker.getTypeArguments(type)[0]; for (let i = index; i < node.arguments.length; i++) { checkThenableOrVoidArgument( checker, @@ -570,7 +570,7 @@ function voidFunctionArguments( } else if (checker.isTupleType(type)) { // Check each type in the tuple - for example, [boolean, () => void] would // add the index of the second tuple parameter to 'voidReturnIndices' - const typeArgs = getTypeArguments(type, checker); + const typeArgs = checker.getTypeArguments(type); for ( let i = index; i < node.arguments.length && i - index < typeArgs.length; diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-type-arguments.ts b/packages/eslint-plugin/src/rules/no-unnecessary-type-arguments.ts index d766257d6c6c..356e39af93ff 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-type-arguments.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-type-arguments.ts @@ -6,7 +6,6 @@ import { createRule, findFirstResult, getParserServices, - getTypeArguments, isTypeReferenceType, } from '../util'; @@ -51,7 +50,7 @@ export default createRule<[], MessageIds>({ if (isTypeReferenceType(type)) { return { type: type.target, - typeArguments: getTypeArguments(type, checker), + typeArguments: checker.getTypeArguments(type), }; } return { diff --git a/packages/eslint-plugin/src/rules/no-unsafe-argument.ts b/packages/eslint-plugin/src/rules/no-unsafe-argument.ts index fe74d1360969..a04440f383c3 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-argument.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-argument.ts @@ -5,7 +5,6 @@ import * as ts from 'typescript'; import { createRule, getParserServices, - getTypeArguments, isTypeAnyArrayType, isTypeAnyType, isUnsafeAssignment, @@ -64,13 +63,13 @@ class FunctionSignature { // is a rest param if (checker.isArrayType(type)) { restType = { - type: getTypeArguments(type, checker)[0], + type: checker.getTypeArguments(type)[0], kind: RestTypeKind.Array, index: i, }; } else if (checker.isTupleType(type)) { restType = { - typeArguments: getTypeArguments(type, checker), + typeArguments: checker.getTypeArguments(type), kind: RestTypeKind.Tuple, index: i, }; @@ -205,10 +204,8 @@ export default createRule<[], MessageIds>({ }); } else if (checker.isTupleType(spreadArgType)) { // foo(...[tuple1, tuple2]) - const spreadTypeArguments = getTypeArguments( - spreadArgType, - checker, - ); + const spreadTypeArguments = + checker.getTypeArguments(spreadArgType); for (const tupleType of spreadTypeArguments) { const parameterType = signature.getNextParameterType(); if (parameterType == null) { diff --git a/packages/eslint-plugin/src/rules/no-unsafe-assignment.ts b/packages/eslint-plugin/src/rules/no-unsafe-assignment.ts index c16a4904756b..4ce2f6db99a3 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-assignment.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-assignment.ts @@ -9,7 +9,6 @@ import { getContextualType, getParserServices, getThisExpression, - getTypeArguments, isTypeAnyArrayType, isTypeAnyType, isTypeUnknownType, @@ -97,7 +96,7 @@ export default createRule({ return true; } - const tupleElements = getTypeArguments(senderType, checker); + const tupleElements = checker.getTypeArguments(senderType); // tuple with any // const [x] = [1 as any]; diff --git a/packages/eslint-plugin/src/rules/require-array-sort-compare.ts b/packages/eslint-plugin/src/rules/require-array-sort-compare.ts index 4097362bb247..1b2916ea0b48 100644 --- a/packages/eslint-plugin/src/rules/require-array-sort-compare.ts +++ b/packages/eslint-plugin/src/rules/require-array-sort-compare.ts @@ -4,7 +4,6 @@ import { createRule, getConstrainedTypeAtLocation, getParserServices, - getTypeArguments, getTypeName, isTypeArrayTypeOrUnionOfArrayTypes, } from '../util'; @@ -61,7 +60,7 @@ export default createRule({ const type = services.getTypeAtLocation(node); if (checker.isArrayType(type) || checker.isTupleType(type)) { - const typeArgs = getTypeArguments(type, checker); + const typeArgs = checker.getTypeArguments(type); return typeArgs.every(arg => getTypeName(checker, arg) === 'string'); } return false; diff --git a/packages/rule-schema-to-typescript-types/src/generateArrayType.ts b/packages/rule-schema-to-typescript-types/src/generateArrayType.ts index 3efe5ed0af1b..f8a551c61092 100644 --- a/packages/rule-schema-to-typescript-types/src/generateArrayType.ts +++ b/packages/rule-schema-to-typescript-types/src/generateArrayType.ts @@ -24,11 +24,7 @@ export function generateArrayType( // but that's obviously dumb and loose so let's not even bother with it throw new UnexpectedError('Unexpected missing items', schema); } - if ( - schema.items && - !TSUtils.isArray(schema.items) && - schema.additionalItems - ) { + if (!TSUtils.isArray(schema.items) && schema.additionalItems) { throw new NotSupportedError( 'singlely-typed array with additionalItems', schema, diff --git a/packages/rule-tester/src/utils/config-validator.ts b/packages/rule-tester/src/utils/config-validator.ts index 34b65987444c..d3690bc9ba17 100644 --- a/packages/rule-tester/src/utils/config-validator.ts +++ b/packages/rule-tester/src/utils/config-validator.ts @@ -24,7 +24,7 @@ const { ConfigOps, environments: BuiltInEnvironments } = Legacy; const ajv = ajvBuilder(); const ruleValidators = new WeakMap(); -let validateSchema: ValidateFunction; +let validateSchema: ValidateFunction | undefined; const severityMap = { error: 2, warn: 1, @@ -40,8 +40,10 @@ function validateRuleSeverity(options: Linter.RuleEntry): number | string { const severity = Array.isArray(options) ? options[0] : options; const normSeverity = typeof severity === 'string' - ? severityMap[severity.toLowerCase() as Linter.SeverityString] - : severity; + ? (severityMap[severity.toLowerCase() as Linter.SeverityString] as + | number + | undefined) + : (severity as number); if (normSeverity === 0 || normSeverity === 1 || normSeverity === 2) { return normSeverity; diff --git a/packages/rule-tester/src/utils/getRuleOptionsSchema.ts b/packages/rule-tester/src/utils/getRuleOptionsSchema.ts index 51f94711f701..1ff81d658e8e 100644 --- a/packages/rule-tester/src/utils/getRuleOptionsSchema.ts +++ b/packages/rule-tester/src/utils/getRuleOptionsSchema.ts @@ -10,7 +10,9 @@ import { isReadonlyArray } from './isReadonlyArray'; * @param rule A new-style rule object * @returns JSON Schema for the rule's options. */ -export function getRuleOptionsSchema(rule: AnyRuleModule): JSONSchema4 | null { +export function getRuleOptionsSchema( + rule: Partial, +): JSONSchema4 | null { const schema = rule.meta?.schema; // Given a tuple of schemas, insert warning level at the beginning diff --git a/packages/rule-tester/src/utils/interpolate.ts b/packages/rule-tester/src/utils/interpolate.ts index 0b3266fefb9b..53e5aa351938 100644 --- a/packages/rule-tester/src/utils/interpolate.ts +++ b/packages/rule-tester/src/utils/interpolate.ts @@ -4,7 +4,7 @@ import type { ReportDescriptorMessageData } from '@typescript-eslint/utils/ts-es export function interpolate( text: string, - data: ReportDescriptorMessageData, + data: ReportDescriptorMessageData | undefined, ): string { if (!data) { return text; diff --git a/packages/scope-manager/src/referencer/ClassVisitor.ts b/packages/scope-manager/src/referencer/ClassVisitor.ts index b22cc27133c6..33b48c7a103b 100644 --- a/packages/scope-manager/src/referencer/ClassVisitor.ts +++ b/packages/scope-manager/src/referencer/ClassVisitor.ts @@ -75,7 +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); @@ -224,17 +224,7 @@ class ClassVisitor extends Visitor { this.visitMetadataType(node.returnType, withMethodDecorators); this.visitType(node.typeParameters); - // In TypeScript there are a number of function-like constructs which have no body, - // so check it exists before traversing - if (node.body) { - // Skip BlockStatement to prevent creating BlockStatement scope. - if (node.body.type === AST_NODE_TYPES.BlockStatement) { - this.#referencer.visitChildren(node.body); - } else { - this.#referencer.visit(node.body); - } - } - + this.#referencer.visitChildren(node.body); this.#referencer.close(node); } diff --git a/packages/scope-manager/src/referencer/PatternVisitor.ts b/packages/scope-manager/src/referencer/PatternVisitor.ts index 6e1140e18959..51564882ef88 100644 --- a/packages/scope-manager/src/referencer/PatternVisitor.ts +++ b/packages/scope-manager/src/referencer/PatternVisitor.ts @@ -92,12 +92,11 @@ class PatternVisitor extends VisitorBase { } protected Identifier(pattern: TSESTree.Identifier): void { - const lastRestElement = - this.#restElements[this.#restElements.length - 1] ?? null; + const lastRestElement = this.#restElements.at(-1); this.#callback(pattern, { topLevel: pattern === this.#rootPattern, - rest: lastRestElement != null && lastRestElement.argument === pattern, + rest: lastRestElement?.argument === pattern, assignments: this.#assignments, }); } diff --git a/packages/scope-manager/src/referencer/TypeVisitor.ts b/packages/scope-manager/src/referencer/TypeVisitor.ts index 9daa2e64093a..2bb922be4023 100644 --- a/packages/scope-manager/src/referencer/TypeVisitor.ts +++ b/packages/scope-manager/src/referencer/TypeVisitor.ts @@ -2,7 +2,7 @@ import type { TSESTree } from '@typescript-eslint/types'; import { AST_NODE_TYPES } from '@typescript-eslint/types'; import { ParameterDefinition, TypeDefinition } from '../definition'; -import { ScopeType } from '../scope'; +import { type Scope, ScopeType } from '../scope'; import type { Referencer } from './Referencer'; import { Visitor } from './Visitor'; @@ -147,7 +147,7 @@ class TypeVisitor extends Visitor { scope.type === ScopeType.mappedType ) { // search up the scope tree to figure out if we're in a nested type scope - let currentScope = scope.upper; + let currentScope = scope.upper as Scope | undefined; while (currentScope) { if ( currentScope.type === ScopeType.functionType || @@ -186,7 +186,7 @@ class TypeVisitor extends Visitor { this.visit(node.typeParameters); } - node.extends?.forEach(this.visit, this); + node.extends.forEach(this.visit, this); this.visit(node.body); if (node.typeParameters) { diff --git a/packages/scope-manager/src/scope/GlobalScope.ts b/packages/scope-manager/src/scope/GlobalScope.ts index de253e5543d6..6bf32a12f536 100644 --- a/packages/scope-manager/src/scope/GlobalScope.ts +++ b/packages/scope-manager/src/scope/GlobalScope.ts @@ -60,7 +60,7 @@ class GlobalScope extends ScopeBase< // create an implicit global variable from assignment expression const info = ref.maybeImplicitGlobal; const node = info.pattern; - if (node && node.type === AST_NODE_TYPES.Identifier) { + if (node.type === AST_NODE_TYPES.Identifier) { this.defineVariable( node.name, this.implicit.set, diff --git a/packages/scope-manager/src/scope/ScopeBase.ts b/packages/scope-manager/src/scope/ScopeBase.ts index 81c712dff389..1cdb2c98586c 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!; + const upperScopeAsScopeBase = upperScope; this.type = type; this.#dynamic = @@ -240,7 +240,7 @@ abstract class ScopeBase< this.block = block; this.variableScope = this.isVariableScope() ? this - : upperScopeAsScopeBase.variableScope; + : upperScopeAsScopeBase!.variableScope; this.upper = upperScope; /** @@ -249,10 +249,8 @@ abstract class ScopeBase< */ this.isStrict = isStrictScope(this as Scope, block, isMethodDefinition); - if (upperScopeAsScopeBase) { - // this is guaranteed to be correct at runtime - upperScopeAsScopeBase.childScopes.push(this as Scope); - } + // this is guaranteed to be correct at runtime + upperScopeAsScopeBase?.childScopes.push(this as Scope); this.#declaredVariables = scopeManager.declaredVariables; @@ -293,11 +291,7 @@ abstract class ScopeBase< return ( defs.length > 0 && defs.every(def => { - if ( - def.type === DefinitionType.Variable && - def.parent?.type === AST_NODE_TYPES.VariableDeclaration && - def.parent.kind === 'var' - ) { + if (def.type === DefinitionType.Variable && def.parent.kind === 'var') { return false; } return true; @@ -386,10 +380,7 @@ abstract class ScopeBase< } protected delegateToUpperScope(ref: Reference): void { - const upper = this.upper! as AnyScope; - if (upper?.leftToResolve) { - upper.leftToResolve.push(ref); - } + (this.upper as AnyScope | undefined)?.leftToResolve?.push(ref); this.through.push(ref); } diff --git a/packages/scope-manager/tests/types/reference-type.test.ts b/packages/scope-manager/tests/types/reference-type.test.ts index 1ede0488440d..79825f2e9aa6 100644 --- a/packages/scope-manager/tests/types/reference-type.test.ts +++ b/packages/scope-manager/tests/types/reference-type.test.ts @@ -21,7 +21,7 @@ describe('referencing a type - positive', () => { AST_NODE_TYPES.TSTypeAliasDeclaration, n => n.id.name === 'OtherType', ); - expect(variable.references[0].identifier.parent?.parent).toBe( + expect(variable.references[0].identifier.parent.parent).toBe( referencingNode, ); }); @@ -39,7 +39,7 @@ describe('referencing a type - positive', () => { ast, AST_NODE_TYPES.TSTypeAliasDeclaration, ); - expect(variable.references[0].identifier.parent?.parent).toBe( + expect(variable.references[0].identifier.parent.parent).toBe( referencingNode, ); }); @@ -87,7 +87,7 @@ describe('referencing a type - positive', () => { AST_NODE_TYPES.TSTypeAliasDeclaration, n => n.id.name === 'reference1', ); - expect(variable.references[1].identifier.parent?.parent).toBe( + expect(variable.references[1].identifier.parent.parent).toBe( referencingTypeNode, ); // third ref is the variable reference @@ -141,7 +141,7 @@ describe('referencing a type - positive', () => { ast, AST_NODE_TYPES.TSTypeAliasDeclaration, ); - expect(variable.references[1].identifier.parent?.parent).toBe( + expect(variable.references[1].identifier.parent.parent).toBe( referencingNode, ); }); diff --git a/packages/type-utils/src/getContextualType.ts b/packages/type-utils/src/getContextualType.ts index e201874b03a6..8aee05fcb55d 100644 --- a/packages/type-utils/src/getContextualType.ts +++ b/packages/type-utils/src/getContextualType.ts @@ -10,9 +10,6 @@ export function getContextualType( node: ts.Expression, ): ts.Type | undefined { const parent = node.parent; - if (!parent) { - return; - } if (ts.isCallExpression(parent) || ts.isNewExpression(parent)) { if (node === parent.expression) { diff --git a/packages/type-utils/src/getSourceFileOfNode.ts b/packages/type-utils/src/getSourceFileOfNode.ts index 9bd8f77ea464..18e7ca27ecde 100644 --- a/packages/type-utils/src/getSourceFileOfNode.ts +++ b/packages/type-utils/src/getSourceFileOfNode.ts @@ -4,7 +4,7 @@ import * as ts from 'typescript'; * Gets the source file for a given node */ export function getSourceFileOfNode(node: ts.Node): ts.SourceFile { - while (node && node.kind !== ts.SyntaxKind.SourceFile) { + while (node.kind !== ts.SyntaxKind.SourceFile) { node = node.parent; } return node as ts.SourceFile; diff --git a/packages/type-utils/src/getTypeArguments.ts b/packages/type-utils/src/getTypeArguments.ts index 04187cea5afc..06b85cead688 100644 --- a/packages/type-utils/src/getTypeArguments.ts +++ b/packages/type-utils/src/getTypeArguments.ts @@ -1,5 +1,8 @@ import type * as ts from 'typescript'; +/** + * @deprecated This is in TypeScript as of 3.7. + */ export function getTypeArguments( type: ts.TypeReference, checker: ts.TypeChecker, diff --git a/packages/type-utils/src/isTypeReadonly.ts b/packages/type-utils/src/isTypeReadonly.ts index 8cfee5272b14..6362adc500b4 100644 --- a/packages/type-utils/src/isTypeReadonly.ts +++ b/packages/type-utils/src/isTypeReadonly.ts @@ -3,7 +3,6 @@ import type { JSONSchema4 } from '@typescript-eslint/utils/json-schema'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; -import { getTypeArguments } from './getTypeArguments'; import { getTypeOfPropertyOfType } from './propertyTypes'; import type { TypeOrValueSpecifier } from './TypeOrValueSpecifier'; import { @@ -56,9 +55,7 @@ function isTypeReadonlyArrayOrTuple( ): Readonlyness { const checker = program.getTypeChecker(); function checkTypeArguments(arrayType: ts.TypeReference): Readonlyness { - const typeArguments = - // getTypeArguments was only added in TS3.7 - getTypeArguments(arrayType, checker); + const typeArguments = checker.getTypeArguments(arrayType); // this shouldn't happen in reality as: // - tuples require at least 1 type argument diff --git a/packages/type-utils/src/predicates.ts b/packages/type-utils/src/predicates.ts index 7bdae284ecce..fdc79dc45ac0 100644 --- a/packages/type-utils/src/predicates.ts +++ b/packages/type-utils/src/predicates.ts @@ -2,7 +2,6 @@ import debug from 'debug'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; -import { getTypeArguments } from './getTypeArguments'; import { getTypeFlags, isTypeFlagSet } from './typeFlagUtils'; const log = debug('typescript-eslint:eslint-plugin:utils:types'); @@ -101,10 +100,7 @@ export function isTypeAnyArrayType( ): boolean { return ( checker.isArrayType(type) && - isTypeAnyType( - // getTypeArguments was only added in TS3.7 - getTypeArguments(type, checker)[0], - ) + isTypeAnyType(checker.getTypeArguments(type)[0]) ); } @@ -117,10 +113,7 @@ export function isTypeUnknownArrayType( ): boolean { return ( checker.isArrayType(type) && - isTypeUnknownType( - // getTypeArguments was only added in TS3.7 - getTypeArguments(type, checker)[0], - ) + isTypeUnknownType(checker.getTypeArguments(type)[0]) ); }