diff --git a/eslint.config.mjs b/eslint.config.mjs index 67fd1a571b09..454c9b484ae2 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -609,6 +609,7 @@ export default tseslint.config( 'packages/rule-schema-to-typescript-types/src/**/*.ts', 'packages/rule-tester/{src,tests,typings}/**/*.ts', 'packages/scope-manager/{src,tests}/**/*.ts', + 'packages/type-utils/{src,tests,typings}/**/*.ts', 'packages/types/{src,tools}/**/*.ts', 'packages/typescript-eslint/{src,tests}/**/*.ts', 'packages/utils/src/**/*.ts', diff --git a/packages/type-utils/src/TypeOrValueSpecifier.ts b/packages/type-utils/src/TypeOrValueSpecifier.ts index d9c50f315b91..0d476b38a7d0 100644 --- a/packages/type-utils/src/TypeOrValueSpecifier.ts +++ b/packages/type-utils/src/TypeOrValueSpecifier.ts @@ -1,7 +1,8 @@ import type { JSONSchema4 } from '@typescript-eslint/utils/json-schema'; -import * as tsutils from 'ts-api-utils'; import type * as ts from 'typescript'; +import * as tsutils from 'ts-api-utils'; + import { specifierNameMatches } from './typeOrValueSpecifiers/specifierNameMatches'; import { typeDeclaredInFile } from './typeOrValueSpecifiers/typeDeclaredInFile'; import { typeDeclaredInLib } from './typeOrValueSpecifiers/typeDeclaredInLib'; @@ -67,19 +68,17 @@ export type TypeOrValueSpecifier = | string; export const typeOrValueSpecifiersSchema = { - type: 'array', items: { oneOf: [ { type: 'string', }, { - type: 'object', additionalProperties: false, properties: { from: { - type: 'string', enum: ['file'], + type: 'string', }, name: { oneOf: [ @@ -87,12 +86,12 @@ export const typeOrValueSpecifiersSchema = { type: 'string', }, { - type: 'array', - minItems: 1, - uniqueItems: true, items: { type: 'string', }, + minItems: 1, + type: 'array', + uniqueItems: true, }, ], }, @@ -101,14 +100,14 @@ export const typeOrValueSpecifiersSchema = { }, }, required: ['from', 'name'], + type: 'object', }, { - type: 'object', additionalProperties: false, properties: { from: { - type: 'string', enum: ['lib'], + type: 'string', }, name: { oneOf: [ @@ -116,25 +115,25 @@ export const typeOrValueSpecifiersSchema = { type: 'string', }, { - type: 'array', - minItems: 1, - uniqueItems: true, items: { type: 'string', }, + minItems: 1, + type: 'array', + uniqueItems: true, }, ], }, }, required: ['from', 'name'], + type: 'object', }, { - type: 'object', additionalProperties: false, properties: { from: { - type: 'string', enum: ['package'], + type: 'string', }, name: { oneOf: [ @@ -142,12 +141,12 @@ export const typeOrValueSpecifiersSchema = { type: 'string', }, { - type: 'array', - minItems: 1, - uniqueItems: true, items: { type: 'string', }, + minItems: 1, + type: 'array', + uniqueItems: true, }, ], }, @@ -156,9 +155,11 @@ export const typeOrValueSpecifiersSchema = { }, }, required: ['from', 'name', 'package'], + type: 'object', }, ], }, + type: 'array', } as const satisfies JSONSchema4; export function typeMatchesSpecifier( diff --git a/packages/type-utils/src/builtinSymbolLikes.ts b/packages/type-utils/src/builtinSymbolLikes.ts index 7686531a40d3..f8c27524c365 100644 --- a/packages/type-utils/src/builtinSymbolLikes.ts +++ b/packages/type-utils/src/builtinSymbolLikes.ts @@ -73,10 +73,10 @@ export function isReadonlyTypeLike( program: ts.Program, type: ts.Type, predicate?: ( - subType: ts.Type & { + subType: { aliasSymbol: ts.Symbol; aliasTypeArguments: readonly ts.Type[]; - }, + } & ts.Type, ) => boolean, ): boolean { return isBuiltinTypeAliasLike(program, type, subtype => { @@ -89,10 +89,10 @@ export function isBuiltinTypeAliasLike( program: ts.Program, type: ts.Type, predicate: ( - subType: ts.Type & { + subType: { aliasSymbol: ts.Symbol; aliasTypeArguments: readonly ts.Type[]; - }, + } & ts.Type, ) => boolean, ): boolean { return isBuiltinSymbolLikeRecurser(program, type, subtype => { @@ -105,10 +105,10 @@ export function isBuiltinTypeAliasLike( if ( isSymbolFromDefaultLibrary(program, aliasSymbol) && predicate( - subtype as ts.Type & { + subtype as { aliasSymbol: ts.Symbol; aliasTypeArguments: readonly ts.Type[]; - }, + } & ts.Type, ) ) { return true; @@ -121,7 +121,7 @@ export function isBuiltinTypeAliasLike( export function isBuiltinSymbolLike( program: ts.Program, type: ts.Type, - symbolName: string | string[], + symbolName: string[] | string, ): boolean { return isBuiltinSymbolLikeRecurser(program, type, subType => { const symbol = subType.getSymbol(); diff --git a/packages/type-utils/src/getContextualType.ts b/packages/type-utils/src/getContextualType.ts index ed96b0d7f6cf..c89e646778d2 100644 --- a/packages/type-utils/src/getContextualType.ts +++ b/packages/type-utils/src/getContextualType.ts @@ -38,7 +38,7 @@ export function getContextualType( // is RHS of assignment return checker.getTypeAtLocation(parent.left); } else if ( - ![ts.SyntaxKind.TemplateSpan, ts.SyntaxKind.JsxExpression].includes( + ![ts.SyntaxKind.JsxExpression, ts.SyntaxKind.TemplateSpan].includes( parent.kind, ) ) { diff --git a/packages/type-utils/src/index.ts b/packages/type-utils/src/index.ts index 13f8792eb2c4..2667ba3f0384 100644 --- a/packages/type-utils/src/index.ts +++ b/packages/type-utils/src/index.ts @@ -11,8 +11,8 @@ export * from './isUnsafeAssignment'; export * from './predicates'; export * from './propertyTypes'; export * from './requiresQuoting'; -export * from './TypeOrValueSpecifier'; export * from './typeFlagUtils'; +export * from './TypeOrValueSpecifier'; export { getDecorators, getModifiers, diff --git a/packages/type-utils/src/isTypeReadonly.ts b/packages/type-utils/src/isTypeReadonly.ts index cc44a0f5f252..ac6eae03ed0f 100644 --- a/packages/type-utils/src/isTypeReadonly.ts +++ b/packages/type-utils/src/isTypeReadonly.ts @@ -1,10 +1,12 @@ -import { ESLintUtils } from '@typescript-eslint/utils'; import type { JSONSchema4 } from '@typescript-eslint/utils/json-schema'; + +import { ESLintUtils } from '@typescript-eslint/utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; -import { getTypeOfPropertyOfType } from './propertyTypes'; import type { TypeOrValueSpecifier } from './TypeOrValueSpecifier'; + +import { getTypeOfPropertyOfType } from './propertyTypes'; import { typeMatchesSomeSpecifier, typeOrValueSpecifiersSchema, @@ -20,27 +22,27 @@ const enum Readonlyness { } export interface ReadonlynessOptions { - readonly treatMethodsAsReadonly?: boolean; readonly allow?: TypeOrValueSpecifier[]; + readonly treatMethodsAsReadonly?: boolean; } export const readonlynessOptionsSchema = { - type: 'object', additionalProperties: false, properties: { + allow: typeOrValueSpecifiersSchema, treatMethodsAsReadonly: { type: 'boolean', }, - allow: typeOrValueSpecifiersSchema, }, + type: 'object', } satisfies JSONSchema4; export const readonlynessOptionsDefaults: ReadonlynessOptions = { - treatMethodsAsReadonly: false, allow: [], + treatMethodsAsReadonly: false, }; -function hasSymbol(node: ts.Node): node is ts.Node & { symbol: ts.Symbol } { +function hasSymbol(node: ts.Node): node is { symbol: ts.Symbol } & ts.Node { return Object.hasOwn(node, 'symbol'); } diff --git a/packages/type-utils/src/isUnsafeAssignment.ts b/packages/type-utils/src/isUnsafeAssignment.ts index 3f462610a909..41fcc8aab1c1 100644 --- a/packages/type-utils/src/isUnsafeAssignment.ts +++ b/packages/type-utils/src/isUnsafeAssignment.ts @@ -1,7 +1,8 @@ import type { TSESTree } from '@typescript-eslint/utils'; +import type * as ts from 'typescript'; + import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import * as tsutils from 'ts-api-utils'; -import type * as ts from 'typescript'; import { isTypeAnyType, isTypeUnknownType } from './predicates'; @@ -20,7 +21,7 @@ export function isUnsafeAssignment( receiver: ts.Type, checker: ts.TypeChecker, senderNode: TSESTree.Node | null, -): false | { sender: ts.Type; receiver: ts.Type } { +): { receiver: ts.Type; sender: ts.Type } | false { return isUnsafeAssignmentWorker( type, receiver, @@ -36,7 +37,7 @@ function isUnsafeAssignmentWorker( checker: ts.TypeChecker, senderNode: TSESTree.Node | null, visited: Map>, -): false | { sender: ts.Type; receiver: ts.Type } { +): { receiver: ts.Type; sender: ts.Type } | false { if (isTypeAnyType(type)) { // Allow assignment of any ==> unknown. if (isTypeUnknownType(receiver)) { @@ -44,7 +45,7 @@ function isUnsafeAssignmentWorker( } if (!isTypeAnyType(receiver)) { - return { sender: type, receiver }; + return { receiver, sender: type }; } } @@ -107,7 +108,7 @@ function isUnsafeAssignmentWorker( visited, ); if (unsafe) { - return { sender: type, receiver }; + return { receiver, sender: type }; } } diff --git a/packages/type-utils/src/typeOrValueSpecifiers/specifierNameMatches.ts b/packages/type-utils/src/typeOrValueSpecifiers/specifierNameMatches.ts index ac7000f11acb..bd26509c1e12 100644 --- a/packages/type-utils/src/typeOrValueSpecifiers/specifierNameMatches.ts +++ b/packages/type-utils/src/typeOrValueSpecifiers/specifierNameMatches.ts @@ -1,6 +1,7 @@ -import * as tsutils from 'ts-api-utils'; import type * as ts from 'typescript'; +import * as tsutils from 'ts-api-utils'; + export function specifierNameMatches( type: ts.Type, names: string[] | string, diff --git a/packages/type-utils/src/typeOrValueSpecifiers/typeDeclaredInFile.ts b/packages/type-utils/src/typeOrValueSpecifiers/typeDeclaredInFile.ts index 720dfed44ac7..09590c99e186 100644 --- a/packages/type-utils/src/typeOrValueSpecifiers/typeDeclaredInFile.ts +++ b/packages/type-utils/src/typeOrValueSpecifiers/typeDeclaredInFile.ts @@ -1,7 +1,7 @@ -import path from 'node:path'; +import type * as ts from 'typescript'; import { getCanonicalFileName } from '@typescript-eslint/typescript-estree'; -import type * as ts from 'typescript'; +import path from 'node:path'; export function typeDeclaredInFile( relativePath: string | undefined, diff --git a/packages/type-utils/tests/TypeOrValueSpecifier.test.ts b/packages/type-utils/tests/TypeOrValueSpecifier.test.ts index b38b84cbb867..7af6d7dac2b0 100644 --- a/packages/type-utils/tests/TypeOrValueSpecifier.test.ts +++ b/packages/type-utils/tests/TypeOrValueSpecifier.test.ts @@ -1,10 +1,11 @@ -import path from 'node:path'; +import type { TSESTree } from '@typescript-eslint/utils'; import { parseForESLint } from '@typescript-eslint/parser'; -import type { TSESTree } from '@typescript-eslint/utils'; import Ajv from 'ajv'; +import path from 'node:path'; + +import type { TypeOrValueSpecifier } from '../src/TypeOrValueSpecifier'; -import type { TypeOrValueSpecifier } from '../src'; import { typeMatchesSpecifier, typeOrValueSpecifiersSchema } from '../src'; describe('TypeOrValueSpecifier', () => { @@ -130,8 +131,8 @@ describe('TypeOrValueSpecifier', () => { const rootDir = path.join(__dirname, 'fixtures'); const { ast, services } = parseForESLint(code, { disallowAutomaticSingleRunInference: true, - project: './tsconfig.json', filePath: path.join(rootDir, 'file.ts'), + project: './tsconfig.json', tsconfigRootDir: rootDir, }); const type = services diff --git a/packages/type-utils/tests/containsAllTypesByName.test.ts b/packages/type-utils/tests/containsAllTypesByName.test.ts index 69b17b18c724..46933b01f092 100644 --- a/packages/type-utils/tests/containsAllTypesByName.test.ts +++ b/packages/type-utils/tests/containsAllTypesByName.test.ts @@ -1,9 +1,9 @@ -import path from 'node:path'; - -import { parseForESLint } from '@typescript-eslint/parser'; import type { TSESTree } from '@typescript-eslint/typescript-estree'; import type * as ts from 'typescript'; +import { parseForESLint } from '@typescript-eslint/parser'; +import path from 'node:path'; + import { containsAllTypesByName } from '../src'; import { expectToHaveParserServices } from './test-utils/expectToHaveParserServices'; @@ -13,8 +13,8 @@ describe('containsAllTypesByName', () => { function getType(code: string): ts.Type { const { ast, services } = parseForESLint(code, { disallowAutomaticSingleRunInference: true, - project: './tsconfig.json', filePath: path.join(rootDir, 'file.ts'), + project: './tsconfig.json', tsconfigRootDir: rootDir, }); expectToHaveParserServices(services); @@ -68,7 +68,7 @@ describe('containsAllTypesByName', () => { const result = containsAllTypesByName( type, false, - new Set(['Promise', 'Object']), + new Set(['Object', 'Promise']), matchAnyInstead, ); expect(result).toBe(expected); diff --git a/packages/type-utils/tests/getTypeName.test.ts b/packages/type-utils/tests/getTypeName.test.ts index e586018e08a4..7ab59ae0aae7 100644 --- a/packages/type-utils/tests/getTypeName.test.ts +++ b/packages/type-utils/tests/getTypeName.test.ts @@ -1,9 +1,9 @@ -import path from 'node:path'; - -import { parseForESLint } from '@typescript-eslint/parser'; import type { TSESTree } from '@typescript-eslint/typescript-estree'; import type * as ts from 'typescript'; +import { parseForESLint } from '@typescript-eslint/parser'; +import path from 'node:path'; + import { getTypeName } from '../src'; import { expectToHaveParserServices } from './test-utils/expectToHaveParserServices'; @@ -13,8 +13,8 @@ describe('getTypeName', () => { const { ast, services } = parseForESLint(code, { disallowAutomaticSingleRunInference: true, - project: './tsconfig.json', filePath: path.join(rootDir, 'file.ts'), + project: './tsconfig.json', tsconfigRootDir: rootDir, }); expectToHaveParserServices(services); @@ -25,7 +25,7 @@ describe('getTypeName', () => { } function runTest(code: string, expected: string): void { - const { type, checker } = getTypes(code); + const { checker, type } = getTypes(code); const result = getTypeName(checker, type); expect(result).toBe(expected); } diff --git a/packages/type-utils/tests/isSymbolFromDefaultLibrary.test.ts b/packages/type-utils/tests/isSymbolFromDefaultLibrary.test.ts index 5b44c756e476..4f7050fb38d9 100644 --- a/packages/type-utils/tests/isSymbolFromDefaultLibrary.test.ts +++ b/packages/type-utils/tests/isSymbolFromDefaultLibrary.test.ts @@ -1,9 +1,9 @@ -import path from 'node:path'; - -import { parseForESLint } from '@typescript-eslint/parser'; import type { TSESTree } from '@typescript-eslint/typescript-estree'; import type * as ts from 'typescript'; +import { parseForESLint } from '@typescript-eslint/parser'; +import path from 'node:path'; + import { isSymbolFromDefaultLibrary } from '../src'; import { expectToHaveParserServices } from './test-utils/expectToHaveParserServices'; @@ -14,10 +14,10 @@ describe('isSymbolFromDefaultLibrary', () => { program: ts.Program; symbol: ts.Symbol | undefined; } { - const { services, ast } = parseForESLint(code, { + const { ast, services } = parseForESLint(code, { disallowAutomaticSingleRunInference: true, - project: './tsconfig.json', filePath: path.join(rootDir, 'file.ts'), + project: './tsconfig.json', tsconfigRootDir: rootDir, }); expectToHaveParserServices(services); diff --git a/packages/type-utils/tests/isTypeReadonly.test.ts b/packages/type-utils/tests/isTypeReadonly.test.ts index f4a27a68d183..f7405e2e5add 100644 --- a/packages/type-utils/tests/isTypeReadonly.test.ts +++ b/packages/type-utils/tests/isTypeReadonly.test.ts @@ -1,10 +1,11 @@ -import path from 'node:path'; - -import { parseForESLint } from '@typescript-eslint/parser'; import type { TSESTree } from '@typescript-eslint/utils'; import type * as ts from 'typescript'; +import { parseForESLint } from '@typescript-eslint/parser'; +import path from 'node:path'; + import type { ReadonlynessOptions } from '../src/isTypeReadonly'; + import { isTypeReadonly } from '../src/isTypeReadonly'; import { expectToHaveParserServices } from './test-utils/expectToHaveParserServices'; @@ -13,13 +14,13 @@ describe('isTypeReadonly', () => { describe('TSTypeAliasDeclaration ', () => { function getType(code: string): { - type: ts.Type; program: ts.Program; + type: ts.Type; } { const { ast, services } = parseForESLint(code, { disallowAutomaticSingleRunInference: true, - project: './tsconfig.json', filePath: path.join(rootDir, 'file.ts'), + project: './tsconfig.json', tsconfigRootDir: rootDir, }); expectToHaveParserServices(services); @@ -28,10 +29,10 @@ describe('isTypeReadonly', () => { const declaration = ast.body[0] as TSESTree.TSTypeAliasDeclaration; return { + program, type: program .getTypeChecker() .getTypeAtLocation(esTreeNodeToTSNodeMap.get(declaration.id)), - program, }; } @@ -40,7 +41,7 @@ describe('isTypeReadonly', () => { options: ReadonlynessOptions | undefined, expected: boolean, ): void { - const { type, program } = getType(code); + const { program, type } = getType(code); const result = isTypeReadonly(program, type, options); expect(result).toBe(expected); diff --git a/packages/type-utils/tests/isUnsafeAssignment.test.ts b/packages/type-utils/tests/isUnsafeAssignment.test.ts index 4882e28f0550..b4ea26a58438 100644 --- a/packages/type-utils/tests/isUnsafeAssignment.test.ts +++ b/packages/type-utils/tests/isUnsafeAssignment.test.ts @@ -1,9 +1,9 @@ -import path from 'node:path'; - -import { parseForESLint } from '@typescript-eslint/parser'; import type { TSESTree } from '@typescript-eslint/utils'; import type * as ts from 'typescript'; +import { parseForESLint } from '@typescript-eslint/parser'; +import path from 'node:path'; + import { isUnsafeAssignment } from '../src/isUnsafeAssignment'; import { expectToHaveParserServices } from './test-utils/expectToHaveParserServices'; @@ -14,15 +14,15 @@ describe('isUnsafeAssignment', () => { code: string, declarationIndex = 0, ): { + checker: ts.TypeChecker; + receiver: ts.Type; sender: ts.Type; senderNode: TSESTree.Node; - receiver: ts.Type; - checker: ts.TypeChecker; } { const { ast, services } = parseForESLint(code, { disallowAutomaticSingleRunInference: true, - project: './tsconfig.json', filePath: path.join(rootDir, 'file.ts'), + project: './tsconfig.json', tsconfigRootDir: rootDir, }); expectToHaveParserServices(services); @@ -33,10 +33,10 @@ describe('isUnsafeAssignment', () => { ] as TSESTree.VariableDeclaration; const declarator = declaration.declarations[0]; return { + checker, receiver: services.getTypeAtLocation(declarator.id), sender: services.getTypeAtLocation(declarator.init!), senderNode: declarator.init!, - checker, }; } @@ -48,14 +48,14 @@ describe('isUnsafeAssignment', () => { receiverStr: string, ): void { expect(result).toBeTruthy(); - const { sender, receiver } = result as Exclude; + const { receiver, sender } = result as Exclude; expect(checker.typeToString(sender)).toBe(senderStr); expect(checker.typeToString(receiver)).toBe(receiverStr); } it('any to a non-any', () => { - const { sender, receiver, checker } = getTypes( + const { checker, receiver, sender } = getTypes( 'const test: string = (1 as any);', ); @@ -68,7 +68,7 @@ describe('isUnsafeAssignment', () => { }); it('any in a generic position to a non-any', () => { - const { sender, receiver, checker } = getTypes( + const { checker, receiver, sender } = getTypes( 'const test: Set = new Set();', ); @@ -81,7 +81,7 @@ describe('isUnsafeAssignment', () => { }); it('any in a generic position to a non-any (multiple generics)', () => { - const { sender, receiver, checker } = getTypes( + const { checker, receiver, sender } = getTypes( 'const test: Map = new Map();', ); @@ -94,7 +94,7 @@ describe('isUnsafeAssignment', () => { }); it('any[] in a generic position to a non-any[]', () => { - const { sender, receiver, checker } = getTypes( + const { checker, receiver, sender } = getTypes( 'const test: Set = new Set();', ); @@ -107,7 +107,7 @@ describe('isUnsafeAssignment', () => { }); it('any in a generic position to a non-any (nested)', () => { - const { sender, receiver, checker } = getTypes( + const { checker, receiver, sender } = getTypes( 'const test: Set>> = new Set>>();', ); @@ -120,7 +120,7 @@ describe('isUnsafeAssignment', () => { }); it('circular reference', () => { - const { sender, senderNode, receiver, checker } = getTypes( + const { checker, receiver, sender, senderNode } = getTypes( `type T = [string, T[]]; const test: T = ["string", []] as any;`, 1, @@ -137,7 +137,7 @@ describe('isUnsafeAssignment', () => { describe('safe', () => { it('non-any to a non-any', () => { - const { sender, receiver, checker } = getTypes( + const { checker, receiver, sender } = getTypes( 'const test: string = "";', ); @@ -145,13 +145,13 @@ describe('isUnsafeAssignment', () => { }); it('non-any to a any', () => { - const { sender, receiver, checker } = getTypes('const test: any = "";'); + const { checker, receiver, sender } = getTypes('const test: any = "";'); expect(isUnsafeAssignment(sender, receiver, checker, null)).toBeFalsy(); }); it('non-any in a generic position to a non-any', () => { - const { sender, receiver, checker } = getTypes( + const { checker, receiver, sender } = getTypes( 'const test: Set = new Set();', ); @@ -159,7 +159,7 @@ describe('isUnsafeAssignment', () => { }); it('non-any in a generic position to a non-any (multiple generics)', () => { - const { sender, receiver, checker } = getTypes( + const { checker, receiver, sender } = getTypes( 'const test: Map = new Map();', ); @@ -167,7 +167,7 @@ describe('isUnsafeAssignment', () => { }); it('non-any[] in a generic position to a non-any[]', () => { - const { sender, receiver, checker } = getTypes( + const { checker, receiver, sender } = getTypes( 'const test: Set = new Set();', ); @@ -175,7 +175,7 @@ describe('isUnsafeAssignment', () => { }); it('non-any in a generic position to a non-any (nested)', () => { - const { sender, receiver, checker } = getTypes( + const { checker, receiver, sender } = getTypes( 'const test: Set>> = new Set>>();', ); @@ -183,7 +183,7 @@ describe('isUnsafeAssignment', () => { }); it('non-any in a generic position to a any (nested)', () => { - const { sender, receiver, checker } = getTypes( + const { checker, receiver, sender } = getTypes( 'const test: Set>> = new Set>>();', ); @@ -191,7 +191,7 @@ describe('isUnsafeAssignment', () => { }); it('any to a unknown', () => { - const { sender, receiver, checker } = getTypes( + const { checker, receiver, sender } = getTypes( 'const test: unknown = [] as any;', ); @@ -199,7 +199,7 @@ describe('isUnsafeAssignment', () => { }); it('any[] in a generic position to a unknown[]', () => { - const { sender, receiver, checker } = getTypes( + const { checker, receiver, sender } = getTypes( 'const test: unknown[] = [] as any[]', ); @@ -207,7 +207,7 @@ describe('isUnsafeAssignment', () => { }); it('any in a generic position to a unknown (nested)', () => { - const { sender, receiver, checker } = getTypes( + const { checker, receiver, sender } = getTypes( 'const test: Set>> = new Set>>();', ); @@ -216,7 +216,7 @@ describe('isUnsafeAssignment', () => { // https://github.com/typescript-eslint/typescript-eslint/issues/2109 it('special cases the empty map constructor with no generics', () => { - const { sender, senderNode, receiver, checker } = getTypes( + const { checker, receiver, sender, senderNode } = getTypes( 'const test: Map = new Map();', ); @@ -226,7 +226,7 @@ describe('isUnsafeAssignment', () => { }); it('circular reference', () => { - const { sender, senderNode, receiver, checker } = getTypes( + const { checker, receiver, sender, senderNode } = getTypes( `type T = [string, T[]]; const test: T = ["string", []] as T;`, 1, diff --git a/packages/type-utils/tests/typeFlagUtils.test.ts b/packages/type-utils/tests/typeFlagUtils.test.ts index 9bf84e3a0d73..24e66b394158 100644 --- a/packages/type-utils/tests/typeFlagUtils.test.ts +++ b/packages/type-utils/tests/typeFlagUtils.test.ts @@ -1,7 +1,7 @@ -import path from 'node:path'; +import type { TSESTree } from '@typescript-eslint/typescript-estree'; import { parseForESLint } from '@typescript-eslint/parser'; -import type { TSESTree } from '@typescript-eslint/typescript-estree'; +import path from 'node:path'; import * as ts from 'typescript'; import { getTypeFlags, isTypeFlagSet } from '../src'; @@ -13,8 +13,8 @@ describe('typeFlagUtils', () => { function getType(code: string): ts.Type { const { ast, services } = parseForESLint(code, { disallowAutomaticSingleRunInference: true, - project: './tsconfig.json', filePath: path.join(rootDir, 'file.ts'), + project: './tsconfig.json', tsconfigRootDir: rootDir, }); expectToHaveParserServices(services); diff --git a/packages/type-utils/typings/typescript.d.ts b/packages/type-utils/typings/typescript.d.ts index 77df1f1fe5e9..a73a5084d197 100644 --- a/packages/type-utils/typings/typescript.d.ts +++ b/packages/type-utils/typings/typescript.d.ts @@ -4,6 +4,17 @@ declare module 'typescript' { interface TypeChecker { // internal TS APIs + /** + * Return the awaited type of the given type. + * + * TODO: Remove when it's exposed as a public API. + * https://github.com/microsoft/TypeScript/issues/59256 + */ + getAwaitedType(type: Type): Type | undefined; + /** + * Return the type of the given property in the given type, or undefined if no such property exists + */ + getTypeOfPropertyOfType(type: Type, propertyName: string): Type | undefined; /** * @returns `true` if the given type is an array type: * - `Array` @@ -18,17 +29,6 @@ declare module 'typescript' { * - `readonly [foo]` */ isTupleType(type: Type): type is TupleTypeReference; - /** - * Return the type of the given property in the given type, or undefined if no such property exists - */ - getTypeOfPropertyOfType(type: Type, propertyName: string): Type | undefined; - /** - * Return the awaited type of the given type. - * - * TODO: Remove when it's exposed as a public API. - * https://github.com/microsoft/TypeScript/issues/59256 - */ - getAwaitedType(type: Type): Type | undefined; } interface Type {