diff --git a/.cspell.json b/.cspell.json index 21ca6f8fc237..3ee9e639f2e5 100644 --- a/.cspell.json +++ b/.cspell.json @@ -114,7 +114,6 @@ "triaging", "tsconfigs", "tseslint", - "tsutils", "tsvfs", "typedef", "typedefs", diff --git a/docs/Custom_Rules.mdx b/docs/Custom_Rules.mdx index a635d93c989b..cce54c78ad62 100644 --- a/docs/Custom_Rules.mdx +++ b/docs/Custom_Rules.mdx @@ -230,8 +230,8 @@ This rule bans for-of looping over an enum by using the TypeScript type checker ```ts import { ESLintUtils } from '@typescript-eslint/utils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; -import * as tsutils from 'tsutils'; export const rule = createRule({ create(context) { @@ -244,7 +244,7 @@ export const rule = createRule({ const type = services.getTypeAtLocation(node); // 3. Check the TS type using the TypeScript APIs - if (tsutils.isTypeFlagSet(nodeType, ts.TypeFlags.EnumLike)) { + if (tools.isTypeFlagSet(nodeType, ts.TypeFlags.EnumLike)) { context.report({ messageId: 'loopOverEnum', node: node.right, diff --git a/jest.config.base.js b/jest.config.base.js index 707c023f2695..1adc8f85596c 100644 --- a/jest.config.base.js +++ b/jest.config.base.js @@ -11,6 +11,7 @@ module.exports = { 'tsx', 'mts', 'mtsx', + 'cjs', 'js', 'jsx', 'mjs', diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index f7580cf43bb8..fdfa8f35a501 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -53,7 +53,7 @@ "natural-compare-lite": "^1.4.0", "regexpp": "^3.2.0", "semver": "^7.3.7", - "tsutils": "^3.21.0" + "ts-api-tools": "^0.0.15" }, "devDependencies": { "@types/debug": "*", diff --git a/packages/eslint-plugin/src/rules/await-thenable.ts b/packages/eslint-plugin/src/rules/await-thenable.ts index 2e41aab2ea1f..336789905220 100644 --- a/packages/eslint-plugin/src/rules/await-thenable.ts +++ b/packages/eslint-plugin/src/rules/await-thenable.ts @@ -1,4 +1,4 @@ -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as util from '../util'; @@ -31,7 +31,7 @@ export default util.createRule({ const originalNode = services.esTreeNodeToTSNodeMap.get(node); - if (!tsutils.isThenableType(checker, originalNode.expression, type)) { + if (!tools.isThenableType(checker, originalNode.expression, type)) { context.report({ messageId: 'await', node, diff --git a/packages/eslint-plugin/src/rules/dot-notation.ts b/packages/eslint-plugin/src/rules/dot-notation.ts index b94f6bc68e69..df6a502115dc 100644 --- a/packages/eslint-plugin/src/rules/dot-notation.ts +++ b/packages/eslint-plugin/src/rules/dot-notation.ts @@ -1,5 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import type { @@ -75,7 +75,7 @@ export default createRule({ options.allowProtectedClassPropertyAccess; const allowIndexSignaturePropertyAccess = (options.allowIndexSignaturePropertyAccess ?? false) || - tsutils.isCompilerOptionEnabled( + tools.isCompilerOptionEnabled( services.program.getCompilerOptions(), // @ts-expect-error - TS is refining the type to never for some reason 'noPropertyAccessFromIndexSignature', 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 a54bd46a80aa..77bdb724ef9e 100644 --- a/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts +++ b/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts @@ -1,6 +1,6 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import * as util from '../util'; @@ -82,7 +82,7 @@ export default util.createRule({ ): void { const services = util.getParserServices(context); const type = util.getConstrainedTypeAtLocation(services, node); - if (!tsutils.isTypeFlagSet(type, ts.TypeFlags.VoidLike)) { + if (!tools.isTypeFlagSet(type, ts.TypeFlags.VoidLike)) { // not a void expression return; } diff --git a/packages/eslint-plugin/src/rules/no-dynamic-delete.ts b/packages/eslint-plugin/src/rules/no-dynamic-delete.ts index 09d5b5420d8a..325508ff9b60 100644 --- a/packages/eslint-plugin/src/rules/no-dynamic-delete.ts +++ b/packages/eslint-plugin/src/rules/no-dynamic-delete.ts @@ -1,6 +1,6 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as util from '../util'; @@ -97,6 +97,6 @@ function isNecessaryDynamicAccess(property: TSESTree.Expression): boolean { return ( typeof property.value === 'string' && - !tsutils.isValidPropertyAccess(property.value) + !tools.isValidPropertyAccess(property.value) ); } diff --git a/packages/eslint-plugin/src/rules/no-floating-promises.ts b/packages/eslint-plugin/src/rules/no-floating-promises.ts index d6e61e458d51..21006caf1373 100644 --- a/packages/eslint-plugin/src/rules/no-floating-promises.ts +++ b/packages/eslint-plugin/src/rules/no-floating-promises.ts @@ -1,6 +1,6 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import * as util from '../util'; @@ -148,7 +148,7 @@ export default util.createRule({ }; function isHigherPrecedenceThanUnary(node: ts.Node): boolean { - const operator = tsutils.isBinaryExpression(node) + const operator = ts.isBinaryExpression(node) ? node.operatorToken.kind : ts.SyntaxKind.Unknown; const nodePrecedence = util.getOperatorPrecedence(node.kind, operator); @@ -240,7 +240,7 @@ export default util.createRule({ // https://github.com/ajafff/tsutils/blob/49d0d31050b44b81e918eae4fbaf1dfe7b7286af/util/type.ts#L95-L125 function isPromiseLike(checker: ts.TypeChecker, node: ts.Node): boolean { const type = checker.getTypeAtLocation(node); - for (const ty of tsutils.unionTypeParts(checker.getApparentType(type))) { + for (const ty of tools.unionTypeParts(checker.getApparentType(type))) { const then = ty.getProperty('then'); if (then === undefined) { continue; @@ -266,7 +266,7 @@ function hasMatchingSignature( type: ts.Type, matcher: (signature: ts.Signature) => boolean, ): boolean { - for (const t of tsutils.unionTypeParts(type)) { + for (const t of tools.unionTypeParts(type)) { if (t.getCallSignatures().some(matcher)) { return true; } @@ -283,7 +283,7 @@ function isFunctionParam( const type: ts.Type | undefined = checker.getApparentType( checker.getTypeOfSymbolAtLocation(param, node), ); - for (const t of tsutils.unionTypeParts(type)) { + for (const t of tools.unionTypeParts(type)) { if (t.getCallSignatures().length !== 0) { return true; } diff --git a/packages/eslint-plugin/src/rules/no-implied-eval.ts b/packages/eslint-plugin/src/rules/no-implied-eval.ts index c1cdcfbbd21d..f14742a3c7a4 100644 --- a/packages/eslint-plugin/src/rules/no-implied-eval.ts +++ b/packages/eslint-plugin/src/rules/no-implied-eval.ts @@ -1,6 +1,6 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import * as util from '../util'; @@ -69,7 +69,7 @@ export default util.createRule({ if ( symbol && - tsutils.isSymbolFlagSet( + tools.isSymbolFlagSet( symbol, ts.SymbolFlags.Function | ts.SymbolFlags.Method, ) diff --git a/packages/eslint-plugin/src/rules/no-meaningless-void-operator.ts b/packages/eslint-plugin/src/rules/no-meaningless-void-operator.ts index c585b13f7852..7cfb1822fc72 100644 --- a/packages/eslint-plugin/src/rules/no-meaningless-void-operator.ts +++ b/packages/eslint-plugin/src/rules/no-meaningless-void-operator.ts @@ -1,6 +1,6 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { ESLintUtils } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import * as util from '../util'; @@ -61,7 +61,7 @@ export default util.createRule< }; const argType = services.getTypeAtLocation(node.argument); - const unionParts = tsutils.unionTypeParts(argType); + const unionParts = tools.unionTypeParts(argType); if ( unionParts.every( part => part.flags & (ts.TypeFlags.Void | ts.TypeFlags.Undefined), diff --git a/packages/eslint-plugin/src/rules/no-misused-promises.ts b/packages/eslint-plugin/src/rules/no-misused-promises.ts index 9d0e3b4a6394..21f325396031 100644 --- a/packages/eslint-plugin/src/rules/no-misused-promises.ts +++ b/packages/eslint-plugin/src/rules/no-misused-promises.ts @@ -1,6 +1,6 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import * as util from '../util'; @@ -410,8 +410,8 @@ export default util.createRule({ function isSometimesThenable(checker: ts.TypeChecker, node: ts.Node): boolean { const type = checker.getTypeAtLocation(node); - for (const subType of tsutils.unionTypeParts(checker.getApparentType(type))) { - if (tsutils.isThenableType(checker, node, subType)) { + for (const subType of tools.unionTypeParts(checker.getApparentType(type))) { + if (tools.isThenableType(checker, node, subType)) { return true; } } @@ -426,7 +426,7 @@ function isSometimesThenable(checker: ts.TypeChecker, node: ts.Node): boolean { function isAlwaysThenable(checker: ts.TypeChecker, node: ts.Node): boolean { const type = checker.getTypeAtLocation(node); - for (const subType of tsutils.unionTypeParts(checker.getApparentType(type))) { + for (const subType of tools.unionTypeParts(checker.getApparentType(type))) { const thenProp = subType.getProperty('then'); // If one of the alternates has no then property, it is not thenable in all @@ -440,7 +440,7 @@ function isAlwaysThenable(checker: ts.TypeChecker, node: ts.Node): boolean { // be of the right form to consider it thenable. const thenType = checker.getTypeOfSymbolAtLocation(thenProp, node); let hasThenableSignature = false; - for (const subType of tsutils.unionTypeParts(thenType)) { + for (const subType of tools.unionTypeParts(thenType)) { for (const signature of subType.getCallSignatures()) { if ( signature.parameters.length !== 0 && @@ -478,7 +478,7 @@ function isFunctionParam( const type: ts.Type | undefined = checker.getApparentType( checker.getTypeOfSymbolAtLocation(param, node), ); - for (const subType of tsutils.unionTypeParts(type)) { + for (const subType of tools.unionTypeParts(type)) { if (subType.getCallSignatures().length !== 0) { return true; } @@ -527,7 +527,7 @@ function voidFunctionArguments( // We can't use checker.getResolvedSignature because it prefers an early '() => void' over a later '() => Promise' // See https://github.com/microsoft/TypeScript/issues/48077 - for (const subType of tsutils.unionTypeParts(type)) { + for (const subType of tools.unionTypeParts(type)) { // Standard function calls and `new` have two different types of signatures const signatures = ts.isCallExpression(node) ? subType.getCallSignatures() @@ -610,7 +610,7 @@ function anySignatureIsThenableType( ): boolean { for (const signature of type.getCallSignatures()) { const returnType = signature.getReturnType(); - if (tsutils.isThenableType(checker, node, returnType)) { + if (tools.isThenableType(checker, node, returnType)) { return true; } } @@ -626,7 +626,7 @@ function isThenableReturningFunctionType( node: ts.Node, type: ts.Type, ): boolean { - for (const subType of tsutils.unionTypeParts(type)) { + for (const subType of tools.unionTypeParts(type)) { if (anySignatureIsThenableType(checker, node, subType)) { return true; } @@ -645,17 +645,17 @@ function isVoidReturningFunctionType( ): boolean { let hadVoidReturn = false; - for (const subType of tsutils.unionTypeParts(type)) { + for (const subType of tools.unionTypeParts(type)) { for (const signature of subType.getCallSignatures()) { const returnType = signature.getReturnType(); // If a certain positional argument accepts both thenable and void returns, // a promise-returning function is valid - if (tsutils.isThenableType(checker, node, returnType)) { + if (tools.isThenableType(checker, node, returnType)) { return false; } - hadVoidReturn ||= tsutils.isTypeFlagSet(returnType, ts.TypeFlags.Void); + hadVoidReturn ||= tools.isTypeFlagSet(returnType, ts.TypeFlags.Void); } } diff --git a/packages/eslint-plugin/src/rules/no-redundant-type-constituents.ts b/packages/eslint-plugin/src/rules/no-redundant-type-constituents.ts index db015edc8392..ae5af074b0b2 100644 --- a/packages/eslint-plugin/src/rules/no-redundant-type-constituents.ts +++ b/packages/eslint-plugin/src/rules/no-redundant-type-constituents.ts @@ -1,5 +1,5 @@ import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import * as util from '../util'; @@ -106,11 +106,11 @@ function describeLiteralType(type: ts.Type): string { return `${type.value.negative ? '-' : ''}${type.value.base10Value}n`; } - if (tsutils.isBooleanLiteralType(type, true)) { + if (tools.isBooleanLiteralType(type, true)) { return 'true'; } - if (tsutils.isBooleanLiteralType(type, false)) { + if (tools.isBooleanLiteralType(type, false)) { return 'false'; } @@ -166,10 +166,10 @@ function isNodeInsideReturnType(node: TSESTree.TSUnionType): boolean { function unionTypePartsUnlessBoolean(type: ts.Type): ts.Type[] { return type.isUnion() && type.types.length === 2 && - tsutils.isBooleanLiteralType(type.types[0], false) && - tsutils.isBooleanLiteralType(type.types[1], true) + tools.isBooleanLiteralType(type.types[0], false) && + tools.isBooleanLiteralType(type.types[1], true) ? [type] - : tsutils.unionTypeParts(type); + : tools.unionTypeParts(type); } export default util.createRule({ diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-boolean-literal-compare.ts b/packages/eslint-plugin/src/rules/no-unnecessary-boolean-literal-compare.ts index 97b05a210aca..36cdd33f7ef7 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-boolean-literal-compare.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-boolean-literal-compare.ts @@ -1,6 +1,6 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import * as util from '../util'; @@ -110,7 +110,7 @@ export default util.createRule({ } function isBooleanType(expressionType: ts.Type): boolean { - return tsutils.isTypeFlagSet( + return tools.isTypeFlagSet( expressionType, ts.TypeFlags.Boolean | ts.TypeFlags.BooleanLiteral, ); @@ -131,7 +131,7 @@ export default util.createRule({ const nonNullishTypes = types.filter( type => - !tsutils.isTypeFlagSet( + !tools.isTypeFlagSet( type, ts.TypeFlags.Undefined | ts.TypeFlags.Null, ), diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts index e3a9e95afbea..14f80ffc8e11 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts @@ -1,13 +1,6 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { - getCallSignaturesOfType, - isBooleanLiteralType, - isFalsyType, - isLiteralType, - isStrictCompilerOptionEnabled, - unionTypeParts, -} from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import { @@ -28,17 +21,19 @@ import { // Truthiness utilities // #region const isTruthyLiteral = (type: ts.Type): boolean => - isBooleanLiteralType(type, true) || (isLiteralType(type) && !!type.value); + tools.isBooleanLiteralType(type, true) || + (tools.isLiteralType(type) && !!type.value); const isPossiblyFalsy = (type: ts.Type): boolean => - unionTypeParts(type) + tools + .unionTypeParts(type) // PossiblyFalsy flag includes literal values, so exclude ones that // are definitely truthy .filter(t => !isTruthyLiteral(t)) .some(type => isTypeFlagSet(type, ts.TypeFlags.PossiblyFalsy)); const isPossiblyTruthy = (type: ts.Type): boolean => - unionTypeParts(type).some(type => !isFalsyType(type)); + tools.unionTypeParts(type).some(type => !tools.isFalsyType(type)); // Nullish utilities const nullishFlag = ts.TypeFlags.Undefined | ts.TypeFlags.Null; @@ -46,19 +41,19 @@ const isNullishType = (type: ts.Type): boolean => isTypeFlagSet(type, nullishFlag); const isPossiblyNullish = (type: ts.Type): boolean => - unionTypeParts(type).some(isNullishType); + tools.unionTypeParts(type).some(isNullishType); const isAlwaysNullish = (type: ts.Type): boolean => - unionTypeParts(type).every(isNullishType); + tools.unionTypeParts(type).every(isNullishType); // isLiteralType only covers numbers and strings, this is a more exhaustive check. const isLiteral = (type: ts.Type): boolean => - isBooleanLiteralType(type, true) || - isBooleanLiteralType(type, false) || + tools.isBooleanLiteralType(type, true) || + tools.isBooleanLiteralType(type, false) || type.flags === ts.TypeFlags.Undefined || type.flags === ts.TypeFlags.Null || type.flags === ts.TypeFlags.Void || - isLiteralType(type); + tools.isLiteralType(type); // #endregion export type Options = [ @@ -150,7 +145,7 @@ export default createRule({ const checker = services.program.getTypeChecker(); const sourceCode = context.getSourceCode(); const compilerOptions = services.program.getCompilerOptions(); - const isStrictNullChecks = isStrictCompilerOptionEnabled( + const isStrictNullChecks = tools.isStrictCompilerOptionEnabled( compilerOptions, 'strictNullChecks', ); @@ -232,12 +227,14 @@ export default createRule({ // Conditional is always necessary if it involves: // `any` or `unknown` or a naked type parameter if ( - unionTypeParts(type).some( - part => - isTypeAnyType(part) || - isTypeUnknownType(part) || - isTypeFlagSet(part, ts.TypeFlags.TypeParameter), - ) + tools + .unionTypeParts(type) + .some( + part => + isTypeAnyType(part) || + isTypeUnknownType(part) || + isTypeFlagSet(part, ts.TypeFlags.TypeParameter), + ) ) { return; } @@ -392,7 +389,7 @@ export default createRule({ */ if ( allowConstantLoopConditions && - isBooleanLiteralType( + tools.isBooleanLiteralType( getConstrainedTypeAtLocation(services, node.test), true, ) @@ -449,9 +446,11 @@ export default createRule({ // (Value to complexity ratio is dubious however) } // Otherwise just do type analysis on the function as a whole. - const returnTypes = getCallSignaturesOfType( - getConstrainedTypeAtLocation(services, callback), - ).map(sig => sig.getReturnType()); + const returnTypes = tools + .getCallSignaturesOfType( + getConstrainedTypeAtLocation(services, callback), + ) + .map(sig => sig.getReturnType()); /* istanbul ignore if */ if (returnTypes.length === 0) { // Not a callable function return; diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-qualifier.ts b/packages/eslint-plugin/src/rules/no-unnecessary-qualifier.ts index 4265dc3d24c4..56c491e05b01 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-qualifier.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-qualifier.ts @@ -1,6 +1,6 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import * as util from '../util'; @@ -34,7 +34,7 @@ export default util.createRule({ symbol: ts.Symbol, checker: ts.TypeChecker, ): ts.Symbol | null { - return tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias) + return tools.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias) ? checker.getAliasedSymbol(symbol) : null; } 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 1860e26a8bd1..2508b0ddaf7d 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-type-arguments.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-type-arguments.ts @@ -1,5 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import * as util from '../util'; @@ -179,7 +179,7 @@ function getAliasedSymbol( symbol: ts.Symbol, checker: ts.TypeChecker, ): ts.Symbol { - return tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias) + return tools.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias) ? checker.getAliasedSymbol(symbol) : symbol; } diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts index 87ef3b9ba42e..6dc0cefabdcf 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts @@ -1,12 +1,6 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { - isObjectFlagSet, - isObjectType, - isStrictCompilerOptionEnabled, - isTypeFlagSet, - isVariableDeclaration, -} from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import * as util from '../util'; @@ -100,10 +94,13 @@ export default util.createRule({ if ( // non-strict mode doesn't care about used before assigned errors - isStrictCompilerOptionEnabled(compilerOptions, 'strictNullChecks') && + tools.isStrictCompilerOptionEnabled( + compilerOptions, + 'strictNullChecks', + ) && // ignore class properties as they are compile time guarded // also ignore function arguments as they can't be used before defined - isVariableDeclaration(declaration) && + ts.isVariableDeclaration(declaration) && // is it `const x!: number` declaration.initializer === undefined && declaration.exclamationToken === undefined && @@ -244,9 +241,9 @@ export default util.createRule({ const castType = services.getTypeAtLocation(node); if ( - isTypeFlagSet(castType, ts.TypeFlags.Literal) || - (isObjectType(castType) && - (isObjectFlagSet(castType, ts.ObjectFlags.Tuple) || + tools.isTypeFlagSet(castType, ts.TypeFlags.Literal) || + (tools.isObjectType(castType) && + (tools.isObjectFlagSet(castType, ts.ObjectFlags.Tuple) || couldBeTupleType(castType))) ) { // It's not always safe to remove a cast to a literal type or tuple diff --git a/packages/eslint-plugin/src/rules/no-unsafe-assignment.ts b/packages/eslint-plugin/src/rules/no-unsafe-assignment.ts index 01cd90b20b8d..c3e3d432f363 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-assignment.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-assignment.ts @@ -1,6 +1,6 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import type * as ts from 'typescript'; import * as util from '../util'; @@ -45,7 +45,7 @@ export default util.createRule({ const services = util.getParserServices(context); const checker = services.program.getTypeChecker(); const compilerOptions = services.program.getCompilerOptions(); - const isNoImplicitThis = tsutils.isStrictCompilerOptionEnabled( + const isNoImplicitThis = tools.isStrictCompilerOptionEnabled( compilerOptions, 'noImplicitThis', ); diff --git a/packages/eslint-plugin/src/rules/no-unsafe-call.ts b/packages/eslint-plugin/src/rules/no-unsafe-call.ts index 216339d26b0e..9b2c08cb10e8 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-call.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-call.ts @@ -1,5 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as util from '../util'; import { getThisExpression } from '../util'; @@ -34,7 +34,7 @@ export default util.createRule<[], MessageIds>({ create(context) { const services = util.getParserServices(context); const compilerOptions = services.program.getCompilerOptions(); - const isNoImplicitThis = tsutils.isStrictCompilerOptionEnabled( + const isNoImplicitThis = tools.isStrictCompilerOptionEnabled( compilerOptions, 'noImplicitThis', ); diff --git a/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts b/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts index a0858af39e44..cc8f57bb4f3d 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts @@ -1,6 +1,6 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as util from '../util'; import { getThisExpression } from '../util'; @@ -35,7 +35,7 @@ export default util.createRule({ create(context) { const services = util.getParserServices(context); const compilerOptions = services.program.getCompilerOptions(); - const isNoImplicitThis = tsutils.isStrictCompilerOptionEnabled( + const isNoImplicitThis = tools.isStrictCompilerOptionEnabled( compilerOptions, 'noImplicitThis', ); diff --git a/packages/eslint-plugin/src/rules/no-unsafe-return.ts b/packages/eslint-plugin/src/rules/no-unsafe-return.ts index 7843f25ffa1a..dc10a68b73b7 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-return.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-return.ts @@ -1,6 +1,6 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as util from '../util'; import { getThisExpression } from '../util'; @@ -30,7 +30,7 @@ export default util.createRule({ const services = util.getParserServices(context); const checker = services.program.getTypeChecker(); const compilerOptions = services.program.getCompilerOptions(); - const isNoImplicitThis = tsutils.isStrictCompilerOptionEnabled( + const isNoImplicitThis = tools.isStrictCompilerOptionEnabled( compilerOptions, 'noImplicitThis', ); @@ -82,7 +82,7 @@ export default util.createRule({ // so we have to use the contextual typing in these cases, i.e. // const foo1: () => Set = () => new Set(); // the return type of the arrow function is Set even though the variable is typed as Set - let functionType = tsutils.isExpression(functionTSNode) + let functionType = tools.isExpression(functionTSNode) ? util.getContextualType(checker, functionTSNode) : services.getTypeAtLocation(functionNode); if (!functionType) { diff --git a/packages/eslint-plugin/src/rules/non-nullable-type-assertion-style.ts b/packages/eslint-plugin/src/rules/non-nullable-type-assertion-style.ts index b42a1c06d409..bda463dd7d98 100644 --- a/packages/eslint-plugin/src/rules/non-nullable-type-assertion-style.ts +++ b/packages/eslint-plugin/src/rules/non-nullable-type-assertion-style.ts @@ -1,6 +1,6 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import * as util from '../util'; @@ -30,20 +30,18 @@ export default util.createRule({ const getTypesIfNotLoose = (node: TSESTree.Node): ts.Type[] | undefined => { const type = services.getTypeAtLocation(node); - if ( - tsutils.isTypeFlagSet(type, ts.TypeFlags.Any | ts.TypeFlags.Unknown) - ) { + if (tools.isTypeFlagSet(type, ts.TypeFlags.Any | ts.TypeFlags.Unknown)) { return undefined; } - return tsutils.unionTypeParts(type); + return tools.unionTypeParts(type); }; const couldBeNullish = (type: ts.Type): boolean => { if (type.flags & ts.TypeFlags.TypeParameter) { const constraint = type.getConstraint(); return constraint == null || couldBeNullish(constraint); - } else if (tsutils.isUnionType(type)) { + } else if (tools.isUnionType(type)) { for (const part of type.types) { if (couldBeNullish(part)) { return true; diff --git a/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts b/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts index 28ec95e5a736..af72186360ca 100644 --- a/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts +++ b/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts @@ -1,6 +1,6 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import * as util from '../util'; @@ -83,7 +83,7 @@ export default util.createRule({ const services = util.getParserServices(context); const compilerOptions = services.program.getCompilerOptions(); const sourceCode = context.getSourceCode(); - const isStrictNullChecks = tsutils.isStrictCompilerOptionEnabled( + const isStrictNullChecks = tools.isStrictCompilerOptionEnabled( compilerOptions, 'strictNullChecks', ); diff --git a/packages/eslint-plugin/src/rules/prefer-optional-chain.ts b/packages/eslint-plugin/src/rules/prefer-optional-chain.ts index 95b910e79093..767c235ec08a 100644 --- a/packages/eslint-plugin/src/rules/prefer-optional-chain.ts +++ b/packages/eslint-plugin/src/rules/prefer-optional-chain.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { isBinaryExpression } from 'tsutils'; import * as ts from 'typescript'; import * as util from '../util'; @@ -76,7 +75,7 @@ export default util.createRule({ const logicalTsNode = services.esTreeNodeToTSNodeMap.get(node); const leftTsNode = services.esTreeNodeToTSNodeMap.get(leftNode); - const operator = isBinaryExpression(logicalTsNode) + const operator = ts.isBinaryExpression(logicalTsNode) ? logicalTsNode.operatorToken.kind : ts.SyntaxKind.Unknown; const leftPrecedence = util.getOperatorPrecedence( diff --git a/packages/eslint-plugin/src/rules/prefer-readonly.ts b/packages/eslint-plugin/src/rules/prefer-readonly.ts index 64d6adb5e890..931fae7f6e01 100644 --- a/packages/eslint-plugin/src/rules/prefer-readonly.ts +++ b/packages/eslint-plugin/src/rules/prefer-readonly.ts @@ -1,6 +1,6 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, ASTUtils } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import * as util from '../util'; @@ -83,7 +83,7 @@ export default util.createRule({ ): void { if ( parent.left === node && - tsutils.isAssignmentKind(parent.operatorToken.kind) + tools.isAssignmentKind(parent.operatorToken.kind) ) { classScope.addVariableModification(node); } @@ -141,7 +141,7 @@ export default util.createRule({ | TSESTree.FunctionDeclaration | TSESTree.FunctionExpression | TSESTree.MethodDefinition, - ): boolean | tsutils.ScopeBoundary { + ): boolean | tools.ScopeBoundary { if (classScopeStack.length === 0) { return false; } @@ -151,7 +151,7 @@ export default util.createRule({ return false; } - return tsutils.isFunctionScopeBoundary(tsNode); + return tools.isFunctionScopeBoundary(tsNode); } function getEsNodesFromViolatingNode( @@ -274,7 +274,7 @@ class ClassScope { private readonly onlyInlineLambdas?: boolean, ) { const classType = checker.getTypeAtLocation(classNode); - if (tsutils.isIntersectionType(classType)) { + if (tools.isIntersectionType(classType)) { this.classType = classType.types[0]; } else { this.classType = classType; @@ -289,8 +289,8 @@ class ClassScope { public addDeclaredVariable(node: ParameterOrPropertyDeclaration): void { if ( - !tsutils.isModifierFlagSet(node, ts.ModifierFlags.Private) || - tsutils.isModifierFlagSet(node, ts.ModifierFlags.Readonly) || + !tools.isModifierFlagSet(node, ts.ModifierFlags.Private) || + tools.isModifierFlagSet(node, ts.ModifierFlags.Readonly) || ts.isComputedPropertyName(node.name) ) { return; @@ -304,7 +304,7 @@ class ClassScope { return; } - (tsutils.isModifierFlagSet(node, ts.ModifierFlags.Static) + (tools.isModifierFlagSet(node, ts.ModifierFlags.Static) ? this.privateModifiableStatics : this.privateModifiableMembers ).set(node.name.getText(), node); @@ -320,8 +320,8 @@ class ClassScope { } const modifyingStatic = - tsutils.isObjectType(modifierType) && - tsutils.isObjectFlagSet(modifierType, ts.ObjectFlags.Anonymous); + tools.isObjectType(modifierType) && + tools.isObjectFlagSet(modifierType, ts.ObjectFlags.Anonymous); if ( !modifyingStatic && this.constructorScopeDepth === DIRECTLY_INSIDE_CONSTRUCTOR @@ -345,7 +345,7 @@ class ClassScope { this.constructorScopeDepth = DIRECTLY_INSIDE_CONSTRUCTOR; for (const parameter of node.parameters) { - if (tsutils.isModifierFlagSet(parameter, ts.ModifierFlags.Private)) { + if (tools.isModifierFlagSet(parameter, ts.ModifierFlags.Private)) { this.addDeclaredVariable(parameter); } } diff --git a/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts b/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts index 413eae49774e..df72cfda39a1 100644 --- a/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts +++ b/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts @@ -1,6 +1,6 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import type * as ts from 'typescript'; import { @@ -134,7 +134,7 @@ export default createRule({ const argumentType = services.getTypeAtLocation(argumentNode); const argumentTypes = collectArgumentTypes( - tsutils.unionTypeParts(argumentType), + tools.unionTypeParts(argumentType), ); switch (argumentTypes) { case ArgumentType.RegExp: diff --git a/packages/eslint-plugin/src/rules/require-await.ts b/packages/eslint-plugin/src/rules/require-await.ts index c9437b4dc7c5..96d1f741e8dd 100644 --- a/packages/eslint-plugin/src/rules/require-await.ts +++ b/packages/eslint-plugin/src/rules/require-await.ts @@ -1,6 +1,6 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import type * as ts from 'typescript'; import * as util from '../util'; @@ -88,7 +88,7 @@ export default util.createRule({ function isThenableType(node: ts.Node): boolean { const type = checker.getTypeAtLocation(node); - return tsutils.isThenableType(checker, node, type); + return tools.isThenableType(checker, node, type); } /** @@ -119,7 +119,7 @@ export default util.createRule({ const type = services.getTypeAtLocation(node.argument); const typesToCheck = expandUnionOrIntersectionType(type); for (const type of typesToCheck) { - const asyncIterator = tsutils.getWellKnownSymbolPropertyOfType( + const asyncIterator = tools.getWellKnownSymbolPropertyOfType( type, 'asyncIterator', checker, diff --git a/packages/eslint-plugin/src/rules/return-await.ts b/packages/eslint-plugin/src/rules/return-await.ts index cddfc4ba8c77..ce71a6bf5062 100644 --- a/packages/eslint-plugin/src/rules/return-await.ts +++ b/packages/eslint-plugin/src/rules/return-await.ts @@ -1,7 +1,6 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; -import { isBinaryExpression } from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import * as util from '../util'; @@ -166,7 +165,7 @@ export default util.createRule({ } function isHigherPrecedenceThanAwait(node: ts.Node): boolean { - const operator = isBinaryExpression(node) + const operator = ts.isBinaryExpression(node) ? node.operatorToken.kind : ts.SyntaxKind.Unknown; const nodePrecedence = getOperatorPrecedence(node.kind, operator); @@ -189,7 +188,7 @@ export default util.createRule({ } const type = checker.getTypeAtLocation(child); - const isThenable = tsutils.isThenableType(checker, expression, type); + const isThenable = tools.isThenableType(checker, expression, type); if (!isAwait && !isThenable) { return; diff --git a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts index b7a18b87cd5d..9812491adf4c 100644 --- a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts +++ b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts @@ -3,7 +3,7 @@ import type { TSESTree, } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import * as util from '../util'; @@ -149,7 +149,7 @@ export default util.createRule({ const checker = services.program.getTypeChecker(); const compilerOptions = services.program.getCompilerOptions(); const sourceCode = context.getSourceCode(); - const isStrictNullChecks = tsutils.isStrictCompilerOptionEnabled( + const isStrictNullChecks = tools.isStrictCompilerOptionEnabled( compilerOptions, 'strictNullChecks', ); @@ -262,7 +262,7 @@ export default util.createRule({ */ function checkNode(node: TSESTree.Node): void { const type = util.getConstrainedTypeAtLocation(services, node); - const types = inspectVariantTypes(tsutils.unionTypeParts(type)); + const types = inspectVariantTypes(tools.unionTypeParts(type)); const is = (...wantedTypes: readonly VariantType[]): boolean => types.size === wantedTypes.length && @@ -766,7 +766,7 @@ export default util.createRule({ if ( types.some(type => - tsutils.isTypeFlagSet( + tools.isTypeFlagSet( type, ts.TypeFlags.Null | ts.TypeFlags.Undefined | ts.TypeFlags.VoidLike, ), @@ -775,15 +775,15 @@ export default util.createRule({ variantTypes.add('nullish'); } const booleans = types.filter(type => - tsutils.isTypeFlagSet(type, ts.TypeFlags.BooleanLike), + tools.isTypeFlagSet(type, ts.TypeFlags.BooleanLike), ); // If incoming type is either "true" or "false", there will be one type // object with intrinsicName set accordingly // If incoming type is boolean, there will be two type objects with - // intrinsicName set "true" and "false" each because of tsutils.unionTypeParts() + // intrinsicName set "true" and "false" each because of ts-api-tools.unionTypeParts() if (booleans.length === 1) { - tsutils.isBooleanLiteralType(booleans[0], true) + tools.isBooleanLiteralType(booleans[0], true) ? variantTypes.add('truthy boolean') : variantTypes.add('boolean'); } else if (booleans.length === 2) { @@ -791,7 +791,7 @@ export default util.createRule({ } const strings = types.filter(type => - tsutils.isTypeFlagSet(type, ts.TypeFlags.StringLike), + tools.isTypeFlagSet(type, ts.TypeFlags.StringLike), ); if (strings.length) { @@ -803,7 +803,7 @@ export default util.createRule({ } const numbers = types.filter(type => - tsutils.isTypeFlagSet( + tools.isTypeFlagSet( type, ts.TypeFlags.NumberLike | ts.TypeFlags.BigIntLike, ), @@ -819,7 +819,7 @@ export default util.createRule({ if ( types.some( type => - !tsutils.isTypeFlagSet( + !tools.isTypeFlagSet( type, ts.TypeFlags.Null | ts.TypeFlags.Undefined | @@ -851,7 +851,7 @@ export default util.createRule({ variantTypes.add('any'); } - if (types.some(type => tsutils.isTypeFlagSet(type, ts.TypeFlags.Never))) { + if (types.some(type => tools.isTypeFlagSet(type, ts.TypeFlags.Never))) { variantTypes.add('never'); } diff --git a/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts b/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts index 76843d12942a..4a5e1f7bf53d 100644 --- a/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts +++ b/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts @@ -1,5 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; -import { isTypeFlagSet, unionTypeParts } from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import { @@ -116,7 +116,7 @@ export default createRule({ const symbolName = discriminantType.getSymbol()?.escapedName; if (discriminantType.isUnion()) { - const unionTypes = unionTypeParts(discriminantType); + const unionTypes = tools.unionTypeParts(discriminantType); const caseTypes: Set = new Set(); for (const switchCase of node.cases) { if (switchCase.test == null) { @@ -144,7 +144,7 @@ export default createRule({ data: { missingBranches: missingBranchTypes .map(missingType => - isTypeFlagSet(missingType, ts.TypeFlags.ESSymbolLike) + tools.isTypeFlagSet(missingType, ts.TypeFlags.ESSymbolLike) ? `typeof ${missingType.getSymbol()?.escapedName as string}` : checker.typeToString(missingType), ) diff --git a/packages/eslint-plugin/src/rules/unbound-method.ts b/packages/eslint-plugin/src/rules/unbound-method.ts index 43971d621b42..1e44957ed811 100644 --- a/packages/eslint-plugin/src/rules/unbound-method.ts +++ b/packages/eslint-plugin/src/rules/unbound-method.ts @@ -1,6 +1,6 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import * as tsutils from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import * as util from '../util'; @@ -162,7 +162,6 @@ export default util.createRule({ ], create(context, [{ ignoreStatic }]) { const services = util.getParserServices(context); - const checker = services.program.getTypeChecker(); const currentSourceFile = services.program.getSourceFile( context.getFilename(), ); @@ -282,7 +281,7 @@ function checkMethod( !thisArgIsVoid && !( ignoreStatic && - tsutils.hasModifier( + tools.hasModifier( getModifiers(valueDeclaration), ts.SyntaxKind.StaticKeyword, ) diff --git a/packages/type-utils/package.json b/packages/type-utils/package.json index 331cec876097..8042e8fdd3f9 100644 --- a/packages/type-utils/package.json +++ b/packages/type-utils/package.json @@ -42,7 +42,7 @@ "@typescript-eslint/typescript-estree": "5.50.0", "@typescript-eslint/utils": "5.50.0", "debug": "^4.3.4", - "tsutils": "^3.21.0" + "ts-api-tools": "^0.0.15" }, "devDependencies": { "@typescript-eslint/parser": "5.50.0", diff --git a/packages/type-utils/src/containsAllTypesByName.ts b/packages/type-utils/src/containsAllTypesByName.ts index 07aa20dac048..715686fe3f78 100644 --- a/packages/type-utils/src/containsAllTypesByName.ts +++ b/packages/type-utils/src/containsAllTypesByName.ts @@ -1,4 +1,4 @@ -import { isTypeReference, isUnionOrIntersectionType } from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import { isTypeFlagSet } from './typeFlagUtils'; @@ -17,7 +17,7 @@ export function containsAllTypesByName( return !allowAny; } - if (isTypeReference(type)) { + if (tools.isTypeReference(type)) { type = type.target; } @@ -26,7 +26,7 @@ export function containsAllTypesByName( return true; } - if (isUnionOrIntersectionType(type)) { + if (tools.isUnionOrIntersectionType(type)) { return type.types.every(t => containsAllTypesByName(t, allowAny, allowedNames), ); diff --git a/packages/type-utils/src/getContextualType.ts b/packages/type-utils/src/getContextualType.ts index 075156282658..b19ceb936bde 100644 --- a/packages/type-utils/src/getContextualType.ts +++ b/packages/type-utils/src/getContextualType.ts @@ -1,14 +1,4 @@ -import { - isBinaryExpression, - isCallExpression, - isIdentifier, - isJsxExpression, - isNewExpression, - isParameterDeclaration, - isPropertyAssignment, - isPropertyDeclaration, - isVariableDeclaration, -} from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; /** @@ -25,23 +15,23 @@ export function getContextualType( return; } - if (isCallExpression(parent) || isNewExpression(parent)) { + if (ts.isCallExpression(parent) || ts.isNewExpression(parent)) { if (node === parent.expression) { // is the callee, so has no contextual type return; } } else if ( - isVariableDeclaration(parent) || - isPropertyDeclaration(parent) || - isParameterDeclaration(parent) + ts.isVariableDeclaration(parent) || + ts.isPropertyDeclaration(parent) || + tools.isParameterDeclaration(parent) ) { return parent.type ? checker.getTypeFromTypeNode(parent.type) : undefined; - } else if (isJsxExpression(parent)) { + } else if (ts.isJsxExpression(parent)) { return checker.getContextualType(parent); - } else if (isPropertyAssignment(parent) && isIdentifier(node)) { + } else if (ts.isPropertyAssignment(parent) && ts.isIdentifier(node)) { return checker.getContextualType(node); } else if ( - isBinaryExpression(parent) && + ts.isBinaryExpression(parent) && parent.operatorToken.kind === ts.SyntaxKind.EqualsToken && parent.right === node ) { diff --git a/packages/type-utils/src/isTypeReadonly.ts b/packages/type-utils/src/isTypeReadonly.ts index 7ba2b300089a..649a38f40a23 100644 --- a/packages/type-utils/src/isTypeReadonly.ts +++ b/packages/type-utils/src/isTypeReadonly.ts @@ -1,13 +1,5 @@ import { ESLintUtils } from '@typescript-eslint/utils'; -import { - isConditionalType, - isIntersectionType, - isObjectType, - isPropertyReadonlyInType, - isSymbolFlagSet, - isUnionType, - unionTypeParts, -} from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import { getTypeOfPropertyOfType } from './propertyTypes'; @@ -136,7 +128,7 @@ function isTypeReadonlyObject( if ( property.valueDeclaration !== undefined && hasSymbol(property.valueDeclaration) && - isSymbolFlagSet( + tools.isSymbolFlagSet( property.valueDeclaration.symbol, ts.SymbolFlags.Method, ) @@ -152,13 +144,15 @@ function isTypeReadonlyObject( if ( lastDeclaration !== undefined && hasSymbol(lastDeclaration) && - isSymbolFlagSet(lastDeclaration.symbol, ts.SymbolFlags.Method) + tools.isSymbolFlagSet(lastDeclaration.symbol, ts.SymbolFlags.Method) ) { continue; } } - if (isPropertyReadonlyInType(type, property.getEscapedName(), checker)) { + if ( + tools.isPropertyReadonlyInType(type, property.getEscapedName(), checker) + ) { continue; } @@ -222,19 +216,21 @@ function isTypeReadonlyRecurser( ): Readonlyness.Readonly | Readonlyness.Mutable { seenTypes.add(type); - if (isUnionType(type)) { + if (tools.isUnionType(type)) { // all types in the union must be readonly - const result = unionTypeParts(type).every( - t => - seenTypes.has(t) || - isTypeReadonlyRecurser(checker, t, options, seenTypes) === - Readonlyness.Readonly, - ); + const result = tools + .unionTypeParts(type) + .every( + t => + seenTypes.has(t) || + isTypeReadonlyRecurser(checker, t, options, seenTypes) === + Readonlyness.Readonly, + ); const readonlyness = result ? Readonlyness.Readonly : Readonlyness.Mutable; return readonlyness; } - if (isIntersectionType(type)) { + if (tools.isIntersectionType(type)) { // Special case for handling arrays/tuples (as readonly arrays/tuples always have mutable methods). if ( type.types.some(t => checker.isArrayType(t) || checker.isTupleType(t)) @@ -260,7 +256,7 @@ function isTypeReadonlyRecurser( } } - if (isConditionalType(type)) { + if (tools.isConditionalType(type)) { const result = [type.root.node.trueType, type.root.node.falseType] .map(checker.getTypeFromTypeNode) .every( @@ -276,7 +272,7 @@ function isTypeReadonlyRecurser( // all non-object, non-intersection types are readonly. // this should only be primitive types - if (!isObjectType(type)) { + if (!tools.isObjectType(type)) { return Readonlyness.Readonly; } diff --git a/packages/type-utils/src/isUnsafeAssignment.ts b/packages/type-utils/src/isUnsafeAssignment.ts index f74220249ad9..e14370da7a93 100644 --- a/packages/type-utils/src/isUnsafeAssignment.ts +++ b/packages/type-utils/src/isUnsafeAssignment.ts @@ -1,6 +1,6 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { isTypeReference } from 'tsutils'; +import * as tools from 'ts-api-tools'; import type * as ts from 'typescript'; import { isTypeAnyType, isTypeUnknownType } from './predicates'; @@ -32,7 +32,7 @@ export function isUnsafeAssignment( } } - if (isTypeReference(type) && isTypeReference(receiver)) { + if (tools.isTypeReference(type) && tools.isTypeReference(receiver)) { // TODO - figure out how to handle cases like this, // where the types are assignable, but not the same type /* diff --git a/packages/type-utils/src/predicates.ts b/packages/type-utils/src/predicates.ts index 72f59e4fc9df..281ad0a188a3 100644 --- a/packages/type-utils/src/predicates.ts +++ b/packages/type-utils/src/predicates.ts @@ -1,5 +1,5 @@ import debug from 'debug'; -import { unionTypeParts } from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import { getTypeArguments } from './getTypeArguments'; @@ -39,7 +39,7 @@ export function isTypeArrayTypeOrUnionOfArrayTypes( type: ts.Type, checker: ts.TypeChecker, ): boolean { - for (const t of unionTypeParts(type)) { + for (const t of tools.unionTypeParts(type)) { if (!checker.isArrayType(t)) { return false; } diff --git a/packages/type-utils/src/typeFlagUtils.ts b/packages/type-utils/src/typeFlagUtils.ts index 134fdcf4ece1..018c2f4de738 100644 --- a/packages/type-utils/src/typeFlagUtils.ts +++ b/packages/type-utils/src/typeFlagUtils.ts @@ -1,4 +1,4 @@ -import { unionTypeParts } from 'tsutils'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; /** @@ -6,7 +6,7 @@ import * as ts from 'typescript'; */ export function getTypeFlags(type: ts.Type): ts.TypeFlags { let flags: ts.TypeFlags = 0; - for (const t of unionTypeParts(type)) { + for (const t of tools.unionTypeParts(type)) { flags |= t.flags; } return flags; diff --git a/packages/typescript-estree/package.json b/packages/typescript-estree/package.json index 180c4f71b69a..244bd5d806f9 100644 --- a/packages/typescript-estree/package.json +++ b/packages/typescript-estree/package.json @@ -48,7 +48,7 @@ "globby": "^11.1.0", "is-glob": "^4.0.3", "semver": "^7.3.7", - "tsutils": "^3.21.0" + "ts-api-tools": "^0.0.15" }, "devDependencies": { "@babel/code-frame": "*", diff --git a/packages/typescript-estree/src/convert-comments.ts b/packages/typescript-estree/src/convert-comments.ts index d4dd9f124a79..0ffcd226bb09 100644 --- a/packages/typescript-estree/src/convert-comments.ts +++ b/packages/typescript-estree/src/convert-comments.ts @@ -1,4 +1,4 @@ -import { forEachComment } from 'tsutils/util/util'; +import * as tools from 'ts-api-tools'; import * as ts from 'typescript'; import { getLocFor } from './node-utils'; @@ -18,7 +18,7 @@ export function convertComments( ): TSESTree.Comment[] { const comments: TSESTree.Comment[] = []; - forEachComment( + tools.forEachComment( ast, (_, comment) => { const type = diff --git a/patches/tsutils+3.21.0.patch b/patches/tsutils+3.21.0.patch deleted file mode 100644 index 0b2e3ee10360..000000000000 --- a/patches/tsutils+3.21.0.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/node_modules/tsutils/util/util.d.ts b/node_modules/tsutils/util/util.d.ts -index 97cedda..4a63900 100644 ---- a/node_modules/tsutils/util/util.d.ts -+++ b/node_modules/tsutils/util/util.d.ts -@@ -9,7 +9,7 @@ export declare function isJsDocKind(kind: ts.SyntaxKind): boolean; - export declare function isKeywordKind(kind: ts.SyntaxKind): boolean; - export declare function isThisParameter(parameter: ts.ParameterDeclaration): boolean; - export declare function getModifier(node: ts.Node, kind: ts.Modifier['kind']): ts.Modifier | undefined; --export declare function hasModifier(modifiers: ts.ModifiersArray | undefined, ...kinds: Array): boolean; -+export declare function hasModifier(modifiers: Iterable | undefined, ...kinds: Array): boolean; - export declare function isParameterProperty(node: ts.ParameterDeclaration): boolean; - export declare function hasAccessModifier(node: ts.ClassElement | ts.ParameterDeclaration): boolean; - export declare const isNodeFlagSet: (node: ts.Node, flag: ts.NodeFlags) => boolean; diff --git a/yarn.lock b/yarn.lock index d5b9b45aa342..ddc6cf42af7e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13659,6 +13659,11 @@ trough@^1.0.0: resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== +ts-api-tools@^0.0.15: + version "0.0.15" + resolved "https://registry.yarnpkg.com/ts-api-tools/-/ts-api-tools-0.0.15.tgz#d16750e0fdf7816a9b91da6af9db5b5167bfca80" + integrity sha512-aNaUSL3j1IvX2xRahC86OHLLhtuEEKful+HfgZs1TcYr2ZcukrENRxDIP1mjXdMojnfr2VflHqsFaaTp1m/bLw== + ts-essentials@^2.0.3: version "2.0.12" resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745" 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