From 17601fca9e269e7250b647cab33215fd1b2b4f61 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 17:59:33 -0500 Subject: [PATCH 01/14] chore(deps): update dependency glob to v11.1.0 (#11786) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 105 ++++++++++++++++++------------------------------------ 1 file changed, 35 insertions(+), 70 deletions(-) diff --git a/yarn.lock b/yarn.lock index 08d0e2f2ee99..31dacc839e4b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11491,25 +11491,20 @@ __metadata: languageName: node linkType: hard -"glob@npm:*, glob@npm:~11.0.2": - version: 11.0.3 - resolution: "glob@npm:11.0.3" +"glob@npm:*": + version: 13.0.0 + resolution: "glob@npm:13.0.0" dependencies: - foreground-child: ^3.3.1 - jackspeak: ^4.1.1 - minimatch: ^10.0.3 + minimatch: ^10.1.1 minipass: ^7.1.2 - package-json-from-dist: ^1.0.0 path-scurry: ^2.0.0 - bin: - glob: dist/esm/bin.mjs - checksum: 65ddc1e3c969e87999880580048763cc8b5bdd375930dd43b8100a5ba481d2e2563e4553de42875790800c602522a98aa8d3ed1c5bd4d27621609e6471eb371d + checksum: 963730222b0acc85a0d2616c08ba3a5d5b5f33fbf69182791967b8a02245db505577a6fc19836d5d58e1cbbfb414ad4f62f605a0372ab05cd9e6998efe944369 languageName: node linkType: hard "glob@npm:^10.3.7, glob@npm:^10.4.1": - version: 10.4.5 - resolution: "glob@npm:10.4.5" + version: 10.5.0 + resolution: "glob@npm:10.5.0" dependencies: foreground-child: ^3.1.0 jackspeak: ^3.1.2 @@ -11519,7 +11514,7 @@ __metadata: path-scurry: ^1.11.1 bin: glob: dist/esm/bin.mjs - checksum: 0bc725de5e4862f9f387fd0f2b274baf16850dcd2714502ccf471ee401803997983e2c05590cb65f9675a3c6f2a58e7a53f9e365704108c6ad3cbf1d60934c4a + checksum: cda96c074878abca9657bd984d2396945cf0d64283f6feeb40d738fe2da642be0010ad5210a1646244a5fc3511b0cab5a374569b3de5a12b8a63d392f18c6043 languageName: node linkType: hard @@ -11549,6 +11544,22 @@ __metadata: languageName: node linkType: hard +"glob@npm:~11.0.2": + version: 11.0.3 + resolution: "glob@npm:11.0.3" + dependencies: + foreground-child: ^3.3.1 + jackspeak: ^4.1.1 + minimatch: ^10.0.3 + minipass: ^7.1.2 + package-json-from-dist: ^1.0.0 + path-scurry: ^2.0.0 + bin: + glob: dist/esm/bin.mjs + checksum: 65ddc1e3c969e87999880580048763cc8b5bdd375930dd43b8100a5ba481d2e2563e4553de42875790800c602522a98aa8d3ed1c5bd4d27621609e6471eb371d + languageName: node + linkType: hard + "global-directory@npm:^4.0.1": version: 4.0.1 resolution: "global-directory@npm:4.0.1" @@ -14991,7 +15002,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:10.0.3, minimatch@npm:^10.0.3, minimatch@npm:~10.0.1": +"minimatch@npm:10.0.3, minimatch@npm:~10.0.1": version: 10.0.3 resolution: "minimatch@npm:10.0.3" dependencies: @@ -15027,6 +15038,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^10.0.3, minimatch@npm:^10.1.1": + version: 10.1.1 + resolution: "minimatch@npm:10.1.1" + dependencies: + "@isaacs/brace-expansion": ^5.0.0 + checksum: 8820c0be92994f57281f0a7a2cc4268dcc4b610f9a1ab666685716b4efe4b5898b43c835a8f22298875b31c7a278a5e3b7e253eee7c886546bb0b61fb94bca6b + languageName: node + linkType: hard + "minimatch@npm:^5.0.1": version: 5.1.6 resolution: "minimatch@npm:5.1.6" @@ -20319,7 +20339,7 @@ __metadata: languageName: node linkType: hard -"vite@npm:7.2.4": +"vite@npm:7.2.4, vite@npm:^5.0.0 || ^6.0.0 || ^7.0.0-0": version: 7.2.4 resolution: "vite@npm:7.2.4" dependencies: @@ -20374,61 +20394,6 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.0.0 || ^6.0.0 || ^7.0.0-0": - version: 7.1.12 - resolution: "vite@npm:7.1.12" - dependencies: - esbuild: ^0.25.0 - fdir: ^6.5.0 - fsevents: ~2.3.3 - picomatch: ^4.0.3 - postcss: ^8.5.6 - rollup: ^4.43.0 - tinyglobby: ^0.2.15 - peerDependencies: - "@types/node": ^20.19.0 || >=22.12.0 - jiti: ">=1.21.0" - less: ^4.0.0 - lightningcss: ^1.21.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: ">=0.54.8" - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - dependenciesMeta: - fsevents: - optional: true - peerDependenciesMeta: - "@types/node": - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - bin: - vite: bin/vite.js - checksum: 4be31af222b94aeaf627443b37e13239ca81bedcf29fb952580272098b966314a5136edf65fbd5b66bbcc84cc1c48403fcadb79d858da4bad455fc9a0da263b7 - languageName: node - linkType: hard - "vitest@npm:^3.1.3": version: 3.2.4 resolution: "vitest@npm:3.2.4" From 97389331fa48fba04be134871a87bc52ce60783c Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Thu, 27 Nov 2025 01:27:21 +0800 Subject: [PATCH 02/14] chore: refactor `createError` for easier use (#11775) * chore: refactor `createError` for easier use * reorder union type * Linting --- .../typescript-estree/src/check-modifiers.ts | 50 +++++++++---------- packages/typescript-estree/src/convert.ts | 14 +----- packages/typescript-estree/src/node-utils.ts | 32 ++++++++++-- 3 files changed, 53 insertions(+), 43 deletions(-) diff --git a/packages/typescript-estree/src/check-modifiers.ts b/packages/typescript-estree/src/check-modifiers.ts index 1a979338dceb..754aa4c14175 100644 --- a/packages/typescript-estree/src/check-modifiers.ts +++ b/packages/typescript-estree/src/check-modifiers.ts @@ -128,18 +128,13 @@ function nodeHasIllegalDecorators( ); } -function throwError(node: ts.Node, message: string): never { - const ast = node.getSourceFile(); - const start = node.getStart(ast); - const end = node.getEnd(); - - throw createError(message, ast, start, end); -} - export function checkModifiers(node: ts.Node): void { // typescript<5.0.0 if (nodeHasIllegalDecorators(node)) { - throwError(node.illegalDecorators[0], 'Decorators are not valid here.'); + throw createError( + node.illegalDecorators[0], + 'Decorators are not valid here.', + ); } for (const decorator of getDecorators( @@ -149,12 +144,12 @@ export function checkModifiers(node: ts.Node): void { // `checkGrammarModifiers` function in typescript if (!nodeCanBeDecorated(node as TSNode)) { if (ts.isMethodDeclaration(node) && !nodeIsPresent(node.body)) { - throwError( + throw createError( decorator, 'A decorator can only decorate a method implementation, not an overload.', ); } else { - throwError(decorator, 'Decorators are not valid here.'); + throw createError(decorator, 'Decorators are not valid here.'); } } } @@ -168,7 +163,7 @@ export function checkModifiers(node: ts.Node): void { node.kind === SyntaxKind.PropertySignature || node.kind === SyntaxKind.MethodSignature ) { - throwError( + throw createError( modifier, `'${ts.tokenToString( modifier.kind, @@ -181,7 +176,7 @@ export function checkModifiers(node: ts.Node): void { (modifier.kind !== SyntaxKind.StaticKeyword || !ts.isClassLike(node.parent)) ) { - throwError( + throw createError( modifier, `'${ts.tokenToString( modifier.kind, @@ -196,7 +191,7 @@ export function checkModifiers(node: ts.Node): void { modifier.kind !== SyntaxKind.ConstKeyword && node.kind === SyntaxKind.TypeParameter ) { - throwError( + throw createError( modifier, `'${ts.tokenToString( modifier.kind, @@ -214,7 +209,7 @@ export function checkModifiers(node: ts.Node): void { ts.isTypeAliasDeclaration(node.parent) )) ) { - throwError( + throw createError( modifier, `'${ts.tokenToString( modifier.kind, @@ -229,7 +224,7 @@ export function checkModifiers(node: ts.Node): void { node.kind !== SyntaxKind.IndexSignature && node.kind !== SyntaxKind.Parameter ) { - throwError( + throw createError( modifier, "'readonly' modifier can only appear on a property declaration or index signature.", ); @@ -240,7 +235,7 @@ export function checkModifiers(node: ts.Node): void { ts.isClassLike(node.parent) && !ts.isPropertyDeclaration(node) ) { - throwError( + throw createError( modifier, `'${ts.tokenToString( modifier.kind, @@ -254,7 +249,7 @@ export function checkModifiers(node: ts.Node): void { ) { const declarationKind = getDeclarationKind(node.declarationList); if (declarationKind === 'using' || declarationKind === 'await using') { - throwError( + throw createError( modifier, `'declare' modifier cannot appear on a '${declarationKind}' declaration.`, ); @@ -270,7 +265,7 @@ export function checkModifiers(node: ts.Node): void { node.kind !== SyntaxKind.GetAccessor && node.kind !== SyntaxKind.SetAccessor ) { - throwError( + throw createError( modifier, `'${ts.tokenToString( modifier.kind, @@ -286,7 +281,7 @@ export function checkModifiers(node: ts.Node): void { (node.parent.kind === SyntaxKind.ModuleBlock || node.parent.kind === SyntaxKind.SourceFile) ) { - throwError( + throw createError( modifier, `'${ts.tokenToString( modifier.kind, @@ -298,7 +293,7 @@ export function checkModifiers(node: ts.Node): void { modifier.kind === SyntaxKind.AccessorKeyword && node.kind !== SyntaxKind.PropertyDeclaration ) { - throwError( + throw createError( modifier, "'accessor' modifier can only appear on a property declaration.", ); @@ -312,7 +307,7 @@ export function checkModifiers(node: ts.Node): void { node.kind !== SyntaxKind.FunctionExpression && node.kind !== SyntaxKind.ArrowFunction ) { - throwError(modifier, "'async' modifier cannot be used here."); + throw createError(modifier, "'async' modifier cannot be used here."); } // `checkGrammarModifiers` function in `typescript` @@ -323,7 +318,7 @@ export function checkModifiers(node: ts.Node): void { modifier.kind === SyntaxKind.DeclareKeyword || modifier.kind === SyntaxKind.AsyncKeyword) ) { - throwError( + throw createError( modifier, `'${ts.tokenToString( modifier.kind, @@ -344,7 +339,10 @@ export function checkModifiers(node: ts.Node): void { anotherModifier.kind === SyntaxKind.ProtectedKeyword || anotherModifier.kind === SyntaxKind.PrivateKeyword) ) { - throwError(anotherModifier, `Accessibility modifier already seen.`); + throw createError( + anotherModifier, + `Accessibility modifier already seen.`, + ); } } } @@ -365,7 +363,7 @@ export function checkModifiers(node: ts.Node): void { if ( !(func?.kind === SyntaxKind.Constructor && nodeIsPresent(func.body)) ) { - throwError( + throw createError( modifier, 'A parameter property is only allowed in a constructor implementation.', ); @@ -397,7 +395,7 @@ export function checkModifiers(node: ts.Node): void { node.kind === SyntaxKind.MethodDeclaration && node.parent.kind === SyntaxKind.ObjectLiteralExpression ) { - throwError( + throw createError( modifier, `'${ts.tokenToString(modifier.kind)}' modifier cannot be used here.`, ); diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 1825bc4d6a37..952b6d30756a 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -57,9 +57,9 @@ export function convertError( error: SemanticOrSyntacticError | ts.DiagnosticWithLocation, ): TSError { return createError( + error.start!, ('message' in error && error.message) || (error.messageText as string), error.file!, - error.start!, ); } @@ -166,18 +166,8 @@ export class Converter { if (this.options.allowInvalidAST) { return; } - let start; - let end; - if (Array.isArray(node)) { - [start, end] = node; - } else if (typeof node === 'number') { - start = end = node; - } else { - start = node.getStart(this.ast); - end = node.getEnd(); - } - throw createError(message, this.ast, start, end); + throw createError(node, message, this.ast); } /** diff --git a/packages/typescript-estree/src/node-utils.ts b/packages/typescript-estree/src/node-utils.ts index b5990014e589..fb0349f7fbb3 100644 --- a/packages/typescript-estree/src/node-utils.ts +++ b/packages/typescript-estree/src/node-utils.ts @@ -678,18 +678,40 @@ export class TSError extends Error { } } +export function createError(node: ts.Node, message: string): TSError; export function createError( + node: number | ts.Node | TSESTree.Range, message: string, - ast: ts.SourceFile, - startIndex: number, - endIndex: number = startIndex, + sourceFile: ts.SourceFile, +): TSError; +export function createError( + node: number | ts.Node | TSESTree.Range, + message: string, + sourceFile?: ts.SourceFile, ): TSError { + let startIndex; + let endIndex; + if (Array.isArray(node)) { + [startIndex, endIndex] = node; + } else if (typeof node === 'number') { + startIndex = endIndex = node; + } else { + sourceFile ??= node.getSourceFile(); + startIndex = node.getStart(sourceFile); + endIndex = node.getEnd(); + } + + if (!sourceFile) { + throw new Error('`sourceFile` is required.'); + } + const [start, end] = [startIndex, endIndex].map(offset => { const { character: column, line } = - ast.getLineAndCharacterOfPosition(offset); + sourceFile.getLineAndCharacterOfPosition(offset); return { column, line: line + 1, offset }; }); - return new TSError(message, ast.fileName, { end, start }); + + return new TSError(message, sourceFile.fileName, { end, start }); } export function nodeHasTokens(n: ts.Node, ast: ts.SourceFile): boolean { From 3252978bf5b88dc4d707b410ecf5c6ac789760bd Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Thu, 27 Nov 2025 02:27:46 +0800 Subject: [PATCH 03/14] chore: fix main branch tests (#11802) --- packages/typescript-estree/src/check-modifiers.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/typescript-estree/src/check-modifiers.ts b/packages/typescript-estree/src/check-modifiers.ts index 754aa4c14175..3c5d52cf702b 100644 --- a/packages/typescript-estree/src/check-modifiers.ts +++ b/packages/typescript-estree/src/check-modifiers.ts @@ -371,7 +371,7 @@ export function checkModifiers(node: ts.Node): void { const param = node as ts.ParameterDeclaration; if (param.dotDotDotToken) { - throwError( + throw createError( modifier, 'A parameter property cannot be a rest parameter.', ); @@ -381,7 +381,7 @@ export function checkModifiers(node: ts.Node): void { param.name.kind === SyntaxKind.ArrayBindingPattern || param.name.kind === SyntaxKind.ObjectBindingPattern ) { - throwError( + throw createError( modifier, 'A parameter property may not be declared using a binding pattern.', ); From 3a50bc34d9ec605c7b98f647443ba060572c97ef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Nov 2025 09:26:28 -0500 Subject: [PATCH 04/14] chore(deps): update dependency webpack to v5.103.0 (#11792) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 90 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/yarn.lock b/yarn.lock index 31dacc839e4b..741f507148f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7583,6 +7583,15 @@ __metadata: languageName: node linkType: hard +"baseline-browser-mapping@npm:^2.8.25": + version: 2.8.31 + resolution: "baseline-browser-mapping@npm:2.8.31" + bin: + baseline-browser-mapping: dist/cli.js + checksum: be21b495093f577c6602882b6c3ecf04a1fe4fcf1d1dd497b51571adcc5815999247f3587a85d194b26f4afad3f726e0fd9d2569087ff09146b044ef8044c9de + languageName: node + linkType: hard + "batch@npm:0.6.1": version: 0.6.1 resolution: "batch@npm:0.6.1" @@ -7714,17 +7723,18 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.23.0, browserslist@npm:^4.24.0, browserslist@npm:^4.24.4, browserslist@npm:^4.24.5": - version: 4.25.0 - resolution: "browserslist@npm:4.25.0" +"browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.23.0, browserslist@npm:^4.24.0, browserslist@npm:^4.24.4, browserslist@npm:^4.24.5, browserslist@npm:^4.26.3": + version: 4.28.0 + resolution: "browserslist@npm:4.28.0" dependencies: - caniuse-lite: ^1.0.30001718 - electron-to-chromium: ^1.5.160 - node-releases: ^2.0.19 - update-browserslist-db: ^1.1.3 + baseline-browser-mapping: ^2.8.25 + caniuse-lite: ^1.0.30001754 + electron-to-chromium: ^1.5.249 + node-releases: ^2.0.27 + update-browserslist-db: ^1.1.4 bin: browserslist: cli.js - checksum: 0d34fa0c6e23e962598ba68ee9f4566a4b575ec550ff7e9e7287c5e94a6e0f208f75f4f7d578ccd060f843167e0e495bde8f6d278f353f0da783cd50f758e5c7 + checksum: c19fe2c6f123851d899d5b207f76de93064e247931e32ca0adcaceb3b48aec65c7c3310c0dc969de96922d488af7de0a0b77b41505e7dfa0a8d3736500748e11 languageName: node linkType: hard @@ -7937,10 +7947,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001702, caniuse-lite@npm:^1.0.30001718": - version: 1.0.30001720 - resolution: "caniuse-lite@npm:1.0.30001720" - checksum: 97b9f9de842595ff9674001abb9c5bc093c03bb985d481ed97617ea48fc248bfb2cc1f1afe19da2bf20016f28793e495fa2f339e22080d8da3c9714fb7950926 +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001702, caniuse-lite@npm:^1.0.30001754": + version: 1.0.30001757 + resolution: "caniuse-lite@npm:1.0.30001757" + checksum: 84ce069d2457f2d2dc68ef9a23870962c89f2bc2a3a67b6b47a431842cfe74a27b8d156b05e5e36f320b501642ecbaf24526963b01468a8b64512ccb8267d135 languageName: node linkType: hard @@ -9631,10 +9641,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.5.160": - version: 1.5.161 - resolution: "electron-to-chromium@npm:1.5.161" - checksum: 80cbed2237eec0349878692600971c57a099d08c1928ae812aa8f7e96cc0220088a4f1854b8bdcb464ec5cb553805bcc69373b49157776ca9828c58539a534d6 +"electron-to-chromium@npm:^1.5.249": + version: 1.5.260 + resolution: "electron-to-chromium@npm:1.5.260" + checksum: 9b0813b195f0bb44ae04fe9bedfdecde38d573dfdc7763ed342203037765c1573f95cfd552a44a8e4a2c55712b055d9de37b8f9388ebc93b829cc37392411ff3 languageName: node linkType: hard @@ -13619,10 +13629,10 @@ __metadata: languageName: node linkType: hard -"loader-runner@npm:^4.2.0": - version: 4.2.0 - resolution: "loader-runner@npm:4.2.0" - checksum: e61aea8b6904b8af53d9de6f0484da86c462c0001f4511bedc837cec63deb9475cea813db62f702cd7930420ccb0e75c78112270ca5c8b61b374294f53c0cb3a +"loader-runner@npm:^4.3.1": + version: 4.3.1 + resolution: "loader-runner@npm:4.3.1" + checksum: 14689a39a79b286d3d15f2199384d6132d62ea707abd6c7e50dc8a1f80c20cbfdd5344f7e6b4a7346974696689ab1a96f8ec7d1e8bf206c5264561502658bd3c languageName: node linkType: hard @@ -15332,10 +15342,10 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.19": - version: 2.0.19 - resolution: "node-releases@npm:2.0.19" - checksum: 917dbced519f48c6289a44830a0ca6dc944c3ee9243c468ebd8515a41c97c8b2c256edb7f3f750416bc37952cc9608684e6483c7b6c6f39f6bd8d86c52cfe658 +"node-releases@npm:^2.0.27": + version: 2.0.27 + resolution: "node-releases@npm:2.0.27" + checksum: a9a54079d894704c2ec728a690b41fbc779a710f5d47b46fa3e460acff08a3e7dfa7108e5599b2db390aa31dac062c47c5118317201f12784188dc5b415f692d languageName: node linkType: hard @@ -18342,15 +18352,15 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^4.0.0, schema-utils@npm:^4.0.1, schema-utils@npm:^4.2.0, schema-utils@npm:^4.3.0, schema-utils@npm:^4.3.2": - version: 4.3.2 - resolution: "schema-utils@npm:4.3.2" +"schema-utils@npm:^4.0.0, schema-utils@npm:^4.0.1, schema-utils@npm:^4.2.0, schema-utils@npm:^4.3.0, schema-utils@npm:^4.3.3": + version: 4.3.3 + resolution: "schema-utils@npm:4.3.3" dependencies: "@types/json-schema": ^7.0.9 ajv: ^8.9.0 ajv-formats: ^2.1.1 ajv-keywords: ^5.1.0 - checksum: d798b341ffa1371f8471629e8861af3aa99e8e15b89da2c0db28c5a80a02ee8c6ffc7daefbe28a2b8c1bc8e3f3e02d028775145d7ab3d9d1a413a9651a835466 + checksum: 4e20404962fd45d5feb5942f7c9ab334a3d3dab94e15001049bd49e2959015f2c59089353953d4976fe664462c79121dea50392968182d4e2c4b75803f822fa3 languageName: node linkType: hard @@ -19469,7 +19479,7 @@ __metadata: languageName: node linkType: hard -"tapable@npm:^2.0.0, tapable@npm:^2.2.0, tapable@npm:^2.2.1, tapable@npm:^2.2.3": +"tapable@npm:^2.0.0, tapable@npm:^2.2.0, tapable@npm:^2.2.1, tapable@npm:^2.3.0": version: 2.3.0 resolution: "tapable@npm:2.3.0" checksum: ada1194219ad550e3626d15019d87a2b8e77521d8463ab1135f46356e987a4c37eff1e87ffdd5acd573590962e519cc81e8ea6f7ed632c66bb58c0f12bd772a4 @@ -20180,9 +20190,9 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.1.3": - version: 1.1.3 - resolution: "update-browserslist-db@npm:1.1.3" +"update-browserslist-db@npm:^1.1.4": + version: 1.1.4 + resolution: "update-browserslist-db@npm:1.1.4" dependencies: escalade: ^3.2.0 picocolors: ^1.1.1 @@ -20190,7 +20200,7 @@ __metadata: browserslist: ">= 4.21.0" bin: update-browserslist-db: cli.js - checksum: 7b6d8d08c34af25ee435bccac542bedcb9e57c710f3c42421615631a80aa6dd28b0a81c9d2afbef53799d482fb41453f714b8a7a0a8003e3b4ec8fb1abb819af + checksum: b757805a63d7954985753c97a48e313abd2d35f2bb10d2bffa65d73a4b81ec9e1305a7b06296819bac8a6b4db8e7be88582487fae2ad7e24731e4ee372b919a6 languageName: node linkType: hard @@ -20634,8 +20644,8 @@ __metadata: linkType: hard "webpack@npm:^5.88.1, webpack@npm:^5.91.0, webpack@npm:^5.95.0": - version: 5.102.0 - resolution: "webpack@npm:5.102.0" + version: 5.103.0 + resolution: "webpack@npm:5.103.0" dependencies: "@types/eslint-scope": ^3.7.7 "@types/estree": ^1.0.8 @@ -20645,7 +20655,7 @@ __metadata: "@webassemblyjs/wasm-parser": ^1.14.1 acorn: ^8.15.0 acorn-import-phases: ^1.0.3 - browserslist: ^4.24.5 + browserslist: ^4.26.3 chrome-trace-event: ^1.0.2 enhanced-resolve: ^5.17.3 es-module-lexer: ^1.2.1 @@ -20654,11 +20664,11 @@ __metadata: glob-to-regexp: ^0.4.1 graceful-fs: ^4.2.11 json-parse-even-better-errors: ^2.3.1 - loader-runner: ^4.2.0 + loader-runner: ^4.3.1 mime-types: ^2.1.27 neo-async: ^2.6.2 - schema-utils: ^4.3.2 - tapable: ^2.2.3 + schema-utils: ^4.3.3 + tapable: ^2.3.0 terser-webpack-plugin: ^5.3.11 watchpack: ^2.4.4 webpack-sources: ^3.3.3 @@ -20667,7 +20677,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: 0df990632239a9127c36acf219f208e9f534fd53b4a4534ab4dbd6904cfbac10e44c73d5d04fd0617f0fe2150fc222f2839d7558b68c3a617855c8b71b8254cb + checksum: dd73cb519423b4a59088e76f446f6a9c51344c53867609790e46a0bd68325033440e3dff24c1f9acd2fa985b703dc01e208b41b889e58dc5642566a9234f9260 languageName: node linkType: hard From d622778288d80644b2a060e2cf6b8a4652a8fd9a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Nov 2025 09:27:41 -0500 Subject: [PATCH 05/14] chore(deps): update dependency markdownlint-cli to ^0.46.0 (#11796) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 85 +++++++++++++++++----------------------------------- 2 files changed, 28 insertions(+), 59 deletions(-) diff --git a/package.json b/package.json index ee1fc0815fd7..1299c0f8764c 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "husky": "^9.1.4", "knip": "^5.41.1", "lint-staged": "^15.2.2", - "markdownlint-cli": "^0.45.0", + "markdownlint-cli": "^0.46.0", "nx": "22.1.1", "prettier": "3.6.2", "rimraf": "^5.0.5", diff --git a/yarn.lock b/yarn.lock index 741f507148f2..4363c547aa33 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6339,7 +6339,7 @@ __metadata: husky: ^9.1.4 knip: ^5.41.1 lint-staged: ^15.2.2 - markdownlint-cli: ^0.45.0 + markdownlint-cli: ^0.46.0 nx: 22.1.1 prettier: 3.6.2 rimraf: ^5.0.5 @@ -8350,14 +8350,14 @@ __metadata: languageName: node linkType: hard -"commander@npm:^13.1.0, commander@npm:~13.1.0": +"commander@npm:^13.1.0": version: 13.1.0 resolution: "commander@npm:13.1.0" checksum: 8ca2fcb33caf2aa06fba3722d7a9440921331d54019dabf906f3603313e7bf334b009b862257b44083ff65d5a3ab19e83ad73af282bd5319f01dc228bdf87ef0 languageName: node linkType: hard -"commander@npm:^14.0.2": +"commander@npm:^14.0.2, commander@npm:~14.0.2": version: 14.0.2 resolution: "commander@npm:14.0.2" checksum: 0a9e549565d368dde2965821833324069b92b099b415c2106996e47db1f0b8c10c77367e9876873c00a52ca627af4c7472eba9b51dc0d6a3ef152ea063d3e9e9 @@ -9244,7 +9244,7 @@ __metadata: languageName: node linkType: hard -"deep-extend@npm:^0.6.0": +"deep-extend@npm:^0.6.0, deep-extend@npm:~0.6.0": version: 0.6.0 resolution: "deep-extend@npm:0.6.0" checksum: 7be7e5a8d468d6b10e6a67c3de828f55001b6eb515d014f7aeb9066ce36bd5717161eb47d6a0f7bed8a9083935b465bc163ee2581c8b128d29bf61092fdf57a7 @@ -11129,7 +11129,7 @@ __metadata: languageName: node linkType: hard -"foreground-child@npm:^3.1.0, foreground-child@npm:^3.3.1": +"foreground-child@npm:^3.1.0": version: 3.3.1 resolution: "foreground-child@npm:3.3.1" dependencies: @@ -11554,22 +11554,6 @@ __metadata: languageName: node linkType: hard -"glob@npm:~11.0.2": - version: 11.0.3 - resolution: "glob@npm:11.0.3" - dependencies: - foreground-child: ^3.3.1 - jackspeak: ^4.1.1 - minimatch: ^10.0.3 - minipass: ^7.1.2 - package-json-from-dist: ^1.0.0 - path-scurry: ^2.0.0 - bin: - glob: dist/esm/bin.mjs - checksum: 65ddc1e3c969e87999880580048763cc8b5bdd375930dd43b8100a5ba481d2e2563e4553de42875790800c602522a98aa8d3ed1c5bd4d27621609e6471eb371d - languageName: node - linkType: hard - "global-directory@npm:^4.0.1": version: 4.0.1 resolution: "global-directory@npm:4.0.1" @@ -12350,7 +12334,7 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^7.0.0, ignore@npm:^7.0.5, ignore@npm:~7.0.4": +"ignore@npm:^7.0.0, ignore@npm:^7.0.5, ignore@npm:~7.0.5": version: 7.0.5 resolution: "ignore@npm:7.0.5" checksum: d0862bf64d3d58bf34d5fb0a9f725bec9ca5ce8cd1aecc8f28034269e8f69b8009ffd79ca3eda96962a6a444687781cd5efdb8c7c8ddc0a6996e36d31c217f14 @@ -13129,15 +13113,6 @@ __metadata: languageName: node linkType: hard -"jackspeak@npm:^4.1.1": - version: 4.1.1 - resolution: "jackspeak@npm:4.1.1" - dependencies: - "@isaacs/cliui": ^8.0.2 - checksum: daca714c5adebfb80932c0b0334025307b68602765098d73d52ec546bc4defdb083292893384261c052742255d0a77d8fcf96f4c669bcb4a99b498b94a74955e - languageName: node - linkType: hard - "jake@npm:^10.8.5": version: 10.8.5 resolution: "jake@npm:10.8.5" @@ -13276,7 +13251,7 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:^4.1.0, js-yaml@npm:^4.1.1, js-yaml@npm:~4.1.0": +"js-yaml@npm:^4.1.0, js-yaml@npm:^4.1.1, js-yaml@npm:~4.1.1": version: 4.1.1 resolution: "js-yaml@npm:4.1.1" dependencies: @@ -13964,30 +13939,31 @@ __metadata: languageName: node linkType: hard -"markdownlint-cli@npm:^0.45.0": - version: 0.45.0 - resolution: "markdownlint-cli@npm:0.45.0" +"markdownlint-cli@npm:^0.46.0": + version: 0.46.0 + resolution: "markdownlint-cli@npm:0.46.0" dependencies: - commander: ~13.1.0 - glob: ~11.0.2 - ignore: ~7.0.4 - js-yaml: ~4.1.0 + commander: ~14.0.2 + deep-extend: ~0.6.0 + ignore: ~7.0.5 + js-yaml: ~4.1.1 jsonc-parser: ~3.3.1 jsonpointer: ~5.0.1 markdown-it: ~14.1.0 - markdownlint: ~0.38.0 - minimatch: ~10.0.1 + markdownlint: ~0.39.0 + minimatch: ~10.1.1 run-con: ~1.3.2 - smol-toml: ~1.3.4 + smol-toml: ~1.5.2 + tinyglobby: ~0.2.15 bin: markdownlint: markdownlint.js - checksum: 41de5e3dd3129e1dd2d136e1a5ed1258c2d5456fb4592c085e76319f3792901e7b910e825e43440df09927769c9259f6f9e79cbaa1047d281b8526cb7b5ca819 + checksum: 9d08bb92aac559ad7406eac8d487d4c81b5e32a912670230d064f48ceb724519f8418e559bdd061465c2cb3dbae4ba46d70f2a8988371089fe4065adc4d39d04 languageName: node linkType: hard -"markdownlint@npm:~0.38.0": - version: 0.38.0 - resolution: "markdownlint@npm:0.38.0" +"markdownlint@npm:~0.39.0": + version: 0.39.0 + resolution: "markdownlint@npm:0.39.0" dependencies: micromark: 4.0.2 micromark-core-commonmark: 2.0.3 @@ -13997,7 +13973,7 @@ __metadata: micromark-extension-gfm-table: 2.1.1 micromark-extension-math: 3.1.0 micromark-util-types: 2.0.2 - checksum: ea684eb78cbc71ebb2d9f79f343e763c627935a1e4ad7524ff08c110b56e4f11ba9c5d7b469441dbb732028ddd7ff6dbe77b460f922506ea78fd8bb248e353d3 + checksum: e25af7c2ee6b377d5f3864e84cb136559abb5958f05bc2ab4306a9b6a2118f149d4540becd69b0f254371fcb920f820762ba9d35164c0c8684e9c5d4969d49bf languageName: node linkType: hard @@ -15012,7 +14988,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:10.0.3, minimatch@npm:~10.0.1": +"minimatch@npm:10.0.3": version: 10.0.3 resolution: "minimatch@npm:10.0.3" dependencies: @@ -15048,7 +15024,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^10.0.3, minimatch@npm:^10.1.1": +"minimatch@npm:^10.1.1, minimatch@npm:~10.1.1": version: 10.1.1 resolution: "minimatch@npm:10.1.1" dependencies: @@ -18802,20 +18778,13 @@ __metadata: languageName: node linkType: hard -"smol-toml@npm:^1.4.2, smol-toml@npm:^1.5.2": +"smol-toml@npm:^1.4.2, smol-toml@npm:^1.5.2, smol-toml@npm:~1.5.2": version: 1.5.2 resolution: "smol-toml@npm:1.5.2" checksum: 75b7e8482151cbe48be094de205631502d5694c2a7d968446799e8b988b4105bd6efd3b6a986baa40d9e9b47cbb2daada21a302901a618793aabd35a670f195e languageName: node linkType: hard -"smol-toml@npm:~1.3.4": - version: 1.3.4 - resolution: "smol-toml@npm:1.3.4" - checksum: ddf333c69b6c848ce6bc89b85096ad8d89cf885cdbf8ca9c5c753df0f5b4a70e3c1984d13e033d68b89a2fff0d984a7f71eb0d3a1c087e934aeda3be71e81d3c - languageName: node - linkType: hard - "snake-case@npm:^3.0.4": version: 3.0.4 resolution: "snake-case@npm:3.0.4" @@ -19621,7 +19590,7 @@ __metadata: languageName: node linkType: hard -"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15": +"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15, tinyglobby@npm:~0.2.15": version: 0.2.15 resolution: "tinyglobby@npm:0.2.15" dependencies: From bb9ba53daf23a7d3d52dfcdf7cdb8bfef69defb7 Mon Sep 17 00:00:00 2001 From: tao <2471314@gmail.com> Date: Sat, 29 Nov 2025 01:17:29 +0800 Subject: [PATCH 06/14] fix(eslint-plugin): [consistent-type-exports] check value flag before resolving alias (#11769) check value flag during iteration --- .../src/rules/consistent-type-exports.ts | 20 +++++++++------- .../fixtures/consistent-type-exports/index.ts | 3 +++ .../rules/consistent-type-exports.test.ts | 24 +++++++++++++++++++ 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/packages/eslint-plugin/src/rules/consistent-type-exports.ts b/packages/eslint-plugin/src/rules/consistent-type-exports.ts index f70d59618514..089d86f24444 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-exports.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-exports.ts @@ -90,18 +90,20 @@ export default createRule({ function isSymbolTypeBased( symbol: ts.Symbol | undefined, ): boolean | undefined { - while (symbol && symbol.flags & ts.SymbolFlags.Alias) { - symbol = checker.getAliasedSymbol(symbol); - if ( - symbol.getDeclarations()?.find(ts.isTypeOnlyImportOrExportDeclaration) - ) { - return true; - } - } if (!symbol || checker.isUnknownSymbol(symbol)) { return undefined; } - return !(symbol.flags & ts.SymbolFlags.Value); + if ( + symbol.getDeclarations()?.some(ts.isTypeOnlyImportOrExportDeclaration) + ) { + return true; + } + if (symbol.flags & ts.SymbolFlags.Value) { + return false; + } + return symbol.flags & ts.SymbolFlags.Alias + ? isSymbolTypeBased(checker.getImmediateAliasedSymbol(symbol)) + : true; } return { diff --git a/packages/eslint-plugin/tests/fixtures/consistent-type-exports/index.ts b/packages/eslint-plugin/tests/fixtures/consistent-type-exports/index.ts index cd6777fd1b68..af2a70f7d321 100644 --- a/packages/eslint-plugin/tests/fixtures/consistent-type-exports/index.ts +++ b/packages/eslint-plugin/tests/fixtures/consistent-type-exports/index.ts @@ -4,3 +4,6 @@ export const value1 = 2; export const value2 = 2; export class Class1 {} + +export type NAME = 'name'; +export const NAME = 'name'; diff --git a/packages/eslint-plugin/tests/rules/consistent-type-exports.test.ts b/packages/eslint-plugin/tests/rules/consistent-type-exports.test.ts index 6226405f4ebb..6863341b5b0f 100644 --- a/packages/eslint-plugin/tests/rules/consistent-type-exports.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-type-exports.test.ts @@ -62,6 +62,11 @@ import * as Foo from './consistent-type-exports'; type Foo = 1; export { Foo } `, + ` +import { Type1 } from './consistent-type-exports'; +const Type1 = 1; +export { Type1 }; + `, ], invalid: [ { @@ -502,5 +507,24 @@ export { export type { Foo }; `, }, + { + code: ` + import { type NAME as Foo } from './consistent-type-exports'; + export { Foo }; + `, + errors: [ + { + column: 9, + endColumn: 24, + endLine: 3, + line: 3, + messageId: 'typeOverValue', + }, + ], + output: ` + import { type NAME as Foo } from './consistent-type-exports'; + export type { Foo }; + `, + }, ], }); From 0db02ac56e6f9119a85ae366611793768f7573e0 Mon Sep 17 00:00:00 2001 From: OleksandraKordonets Date: Fri, 28 Nov 2025 12:19:19 -0500 Subject: [PATCH 07/14] fix(eslint-plugin): honor ignored base types on generic classes (#11767) * fix(eslint-plugin): honor ignored base types on generic classes * Address feedback: apply review style suggestions --------- Co-authored-by: Josh Goldberg --- .../src/rules/no-base-to-string.ts | 32 ++++++++++++------- .../tests/rules/no-base-to-string.test.ts | 15 +++++++++ 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-base-to-string.ts b/packages/eslint-plugin/src/rules/no-base-to-string.ts index 48fca65676ed..600f24fc7ce0 100644 --- a/packages/eslint-plugin/src/rules/no-base-to-string.ts +++ b/packages/eslint-plugin/src/rules/no-base-to-string.ts @@ -211,14 +211,26 @@ export default createRule({ return Usefulness.Always; } - function hasBaseTypes(type: ts.Type): type is ts.InterfaceType { - return ( - tsutils.isObjectType(type) && + function getBaseTypesForType(type: ts.Type): readonly ts.Type[] { + if (!tsutils.isObjectType(type)) { + return []; + } + + const interfaceTarget = tsutils.isTypeReference(type) + ? type.target + : type; + + const interfaceType = tsutils.isObjectFlagSet( - type, + interfaceTarget, ts.ObjectFlags.Interface | ts.ObjectFlags.Class, - ) - ); + ) && (interfaceTarget as ts.InterfaceType); + + if (!interfaceType) { + return []; + } + + return checker.getBaseTypes(interfaceType); } function isIgnoredTypeOrBase( @@ -231,13 +243,9 @@ export default createRule({ seen.add(type); - const typeName = getTypeName(checker, type); return ( - ignoredTypeNames.includes(typeName) || - (hasBaseTypes(type) && - checker - .getBaseTypes(type) - .some(base => isIgnoredTypeOrBase(base, seen))) + ignoredTypeNames.includes(getTypeName(checker, type)) || + getBaseTypesForType(type).some(base => isIgnoredTypeOrBase(base, seen)) ); } diff --git a/packages/eslint-plugin/tests/rules/no-base-to-string.test.ts b/packages/eslint-plugin/tests/rules/no-base-to-string.test.ts index cab11e9ce5ec..c2baf8ee80ab 100644 --- a/packages/eslint-plugin/tests/rules/no-base-to-string.test.ts +++ b/packages/eslint-plugin/tests/rules/no-base-to-string.test.ts @@ -334,6 +334,21 @@ declare const error: MyError; error.toString(); `, }, + { + code: ` + class BaseError extends Error { + code?: string; + } + + class Boom extends BaseError { + details: T; + } + + function bar(error: Boom) { + console.log(error.toString()); + } + `, + }, { code: ` class UnknownBase {} From 3d809f53466736d91c0f79cdf1e9233d86cce448 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 28 Nov 2025 12:19:45 -0500 Subject: [PATCH 08/14] chore(deps): update dependency stylelint to v16.26.0 (#11807) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 131 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 97 insertions(+), 34 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4363c547aa33..101e28c00caf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1558,6 +1558,28 @@ __metadata: languageName: node linkType: hard +"@cacheable/memory@npm:^2.0.6": + version: 2.0.6 + resolution: "@cacheable/memory@npm:2.0.6" + dependencies: + "@cacheable/utils": ^2.3.2 + "@keyv/bigmap": ^1.3.0 + hookified: ^1.13.0 + keyv: ^5.5.4 + checksum: 6f085815b11a61d9f13dcd4bee7f799a45cd20d338f92e512d49db524b50923cba5c09bbc8e1ee15044da55e699711faae33d3765f82a17155c9ab44cdc15923 + languageName: node + linkType: hard + +"@cacheable/utils@npm:^2.3.2": + version: 2.3.2 + resolution: "@cacheable/utils@npm:2.3.2" + dependencies: + hashery: ^1.2.0 + keyv: ^5.5.4 + checksum: 3a1e42095ce9f0af2d5e16967766ac286e905d1794e39f5577982affa23775dc774e37f47f125a93bdb6c4ca7c2d74cc2d141cfebf7ee8de9ea1f3374f0e8572 + languageName: node + linkType: hard + "@colors/colors@npm:1.5.0": version: 1.5.0 resolution: "@colors/colors@npm:1.5.0" @@ -2165,6 +2187,13 @@ __metadata: languageName: node linkType: hard +"@csstools/css-syntax-patches-for-csstree@npm:^1.0.19": + version: 1.0.19 + resolution: "@csstools/css-syntax-patches-for-csstree@npm:1.0.19" + checksum: 0cd74b9db207cd9f6948ffc63ff90bb828b89abcebabe6b3dcf2911786d0a56176be9f72ac049a01c612028a26df95630376321a652be3d66838a8a3c18f124a + languageName: node + linkType: hard + "@csstools/css-tokenizer@npm:^3.0.4": version: 3.0.4 resolution: "@csstools/css-tokenizer@npm:3.0.4" @@ -4192,10 +4221,22 @@ __metadata: languageName: node linkType: hard -"@keyv/serialize@npm:^1.1.0": - version: 1.1.0 - resolution: "@keyv/serialize@npm:1.1.0" - checksum: 84533dc994ff1b9585fb7593542f1d7a9746b843c13c9341a8d2feb2e1fc0136d42e0146f8ff751ad9decc64da4792538e270b95a126f6d0dbb48e349ee462ab +"@keyv/bigmap@npm:^1.3.0": + version: 1.3.0 + resolution: "@keyv/bigmap@npm:1.3.0" + dependencies: + hashery: ^1.2.0 + hookified: ^1.13.0 + peerDependencies: + keyv: ^5.5.4 + checksum: 8e604e1359507a1fb2e45e7ad83d02bd2e1d165dbbc4458f42b6e4016961a6ef429e28338e68e8126a90b28b976ee31e52c1aa39a4227bb1e1e9ede4e9431919 + languageName: node + linkType: hard + +"@keyv/serialize@npm:^1.1.1": + version: 1.1.1 + resolution: "@keyv/serialize@npm:1.1.1" + checksum: 2963ba90a6ca1cad7e4c1ff2de09326841eba4bca90dc52508fdc92ef88972ffd8ae8be48de80cfa9a864617955f146bb6dca700f5790118fefd74880d432ca7 languageName: node linkType: hard @@ -7855,13 +7896,16 @@ __metadata: languageName: node linkType: hard -"cacheable@npm:^1.10.4": - version: 1.10.4 - resolution: "cacheable@npm:1.10.4" +"cacheable@npm:^2.2.0": + version: 2.3.0 + resolution: "cacheable@npm:2.3.0" dependencies: - hookified: ^1.11.0 - keyv: ^5.5.0 - checksum: b146ed94ecb8f8b7d5eabb29bde5f0d10541305e52cae01c44d1ec643969d6afa92d47c9918afea402c5e87ba1f96cb4336cc1030f33d59d2b470e7c4221efb3 + "@cacheable/memory": ^2.0.6 + "@cacheable/utils": ^2.3.2 + hookified: ^1.13.0 + keyv: ^5.5.4 + qified: ^0.5.2 + checksum: f7c071065045e7c7fe2e800745deb5f545ad2ac55f5b7713919bdcc9c5b9328955e295a448dd0626ef1db713f610c8fafaf03e474f767035f943818dcc07967f languageName: node linkType: hard @@ -10957,12 +11001,12 @@ __metadata: languageName: node linkType: hard -"file-entry-cache@npm:^10.1.4": - version: 10.1.4 - resolution: "file-entry-cache@npm:10.1.4" +"file-entry-cache@npm:^11.1.1": + version: 11.1.1 + resolution: "file-entry-cache@npm:11.1.1" dependencies: - flat-cache: ^6.1.13 - checksum: b0fbc1522c62d060a0e17604074f32b68bc964d4dc1a40e1f75d5c731d0e104ffbb39bf61c37a836e0ce1cabb92c121f03ae2da0ee29a3885546937e1962b862 + flat-cache: ^6.1.19 + checksum: 9be8c48c8844d6a20ae59c32171af8b4d2dae8486b7d01e3447dbc9dc3476f33fbbacd734b5c2207f07a76446538b3ab18c2a0241dbbebc55b56727c1c88b833 languageName: node linkType: hard @@ -11083,14 +11127,14 @@ __metadata: languageName: node linkType: hard -"flat-cache@npm:^6.1.13": - version: 6.1.13 - resolution: "flat-cache@npm:6.1.13" +"flat-cache@npm:^6.1.19": + version: 6.1.19 + resolution: "flat-cache@npm:6.1.19" dependencies: - cacheable: ^1.10.4 + cacheable: ^2.2.0 flatted: ^3.3.3 - hookified: ^1.11.0 - checksum: 9a2b402a1e0a0802b5fdb94f4a3d4f2755bdeb2a81927be5fefd93fd7317b0e73b11812239bcc82d29ea36e54b376a5d4a6312edd97e515c45eb5f1d2a2f6659 + hookified: ^1.13.0 + checksum: 32d65dd98d091cfcaa879fc5afa8aa3c0439780a54d4d70035257ce6ffef5bf7f6ddf1be26b1e06446fd52a298700f8b90d626ae05624e40b68d358c40c81d1d languageName: node linkType: hard @@ -11820,6 +11864,15 @@ __metadata: languageName: node linkType: hard +"hashery@npm:^1.2.0": + version: 1.2.0 + resolution: "hashery@npm:1.2.0" + dependencies: + hookified: ^1.13.0 + checksum: b2954f12bd42fe44213554aa7cdcd1f99eadcee4be3a6d31a4038479ab67fa8e0b98e11457357d4225e2795f90d657f5ce49f91df953cb04ae9b6700954ff853 + languageName: node + linkType: hard + "hasown@npm:^2.0.2": version: 2.0.2 resolution: "hasown@npm:2.0.2" @@ -11991,10 +12044,10 @@ __metadata: languageName: node linkType: hard -"hookified@npm:^1.11.0": - version: 1.11.0 - resolution: "hookified@npm:1.11.0" - checksum: 237189d87d3ebafacdb3b27ecdbb7060d359a16ccf6d27896920e6f8b53890c831ff5bafc2224bfcd6562a1effdca28a3edf819af46cf30cc58c142f1ce9b67d +"hookified@npm:^1.13.0": + version: 1.13.0 + resolution: "hookified@npm:1.13.0" + checksum: 2087d5146dfbf8789a16609341d0d524d6acad831b72e1c8ed69dfab226fb2c987fecc06c6808b8a273461aad13e9c6ea37fa254679b86a855a06d65be1c397b languageName: node linkType: hard @@ -13415,12 +13468,12 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^5.5.0": - version: 5.5.0 - resolution: "keyv@npm:5.5.0" +"keyv@npm:^5.5.4": + version: 5.5.4 + resolution: "keyv@npm:5.5.4" dependencies: - "@keyv/serialize": ^1.1.0 - checksum: 7ab64dbcd6f14995f93baf33a82ca1b35c7c7b810f5c59239772904637546eb7ed9695e535420b50bcd5d2ff365cf7ba3a4f1613920249572c5a2a07e1053820 + "@keyv/serialize": ^1.1.1 + checksum: 046f0442721f437d7438584d15ff39aedd4f4979d0e867f83d53372f4b55749b813d6fcd949a2266b644f0d084c3340c2f9dd4e4a1e8a5cb0bfc040674ff16c5 languageName: node linkType: hard @@ -17231,6 +17284,15 @@ __metadata: languageName: node linkType: hard +"qified@npm:^0.5.2": + version: 0.5.2 + resolution: "qified@npm:0.5.2" + dependencies: + hookified: ^1.13.0 + checksum: 66a2cf7bf79fc1d5b3705e694407f913e378c208f94cbfba7757671e6d2978a09dfef9b860a333c07bcb873e17e75ca895d54a652abd2c2df6ed6eda549d1234 + languageName: node + linkType: hard + "qs@npm:6.10.3": version: 6.10.3 resolution: "qs@npm:6.10.3" @@ -19315,10 +19377,11 @@ __metadata: linkType: hard "stylelint@npm:^16.3.1": - version: 16.25.0 - resolution: "stylelint@npm:16.25.0" + version: 16.26.1 + resolution: "stylelint@npm:16.26.1" dependencies: "@csstools/css-parser-algorithms": ^3.0.5 + "@csstools/css-syntax-patches-for-csstree": ^1.0.19 "@csstools/css-tokenizer": ^3.0.4 "@csstools/media-query-list-parser": ^4.0.3 "@csstools/selector-specificity": ^5.0.0 @@ -19331,7 +19394,7 @@ __metadata: debug: ^4.4.3 fast-glob: ^3.3.3 fastest-levenshtein: ^1.0.16 - file-entry-cache: ^10.1.4 + file-entry-cache: ^11.1.1 global-modules: ^2.0.0 globby: ^11.1.0 globjoin: ^0.1.4 @@ -19358,7 +19421,7 @@ __metadata: write-file-atomic: ^5.0.1 bin: stylelint: bin/stylelint.mjs - checksum: 0b36fead063f8903522afd04a350b021670348a0218f580aa895100cc59634179742ff844037d482bbeaff234f3411fc331f2ce59419c807c341ea3e0355d1cc + checksum: 932b8587bfd86ec95d897a61d07d75fcdc9d6d14446faa8afc40119c9cf24ff7dbcde49eab96cdbd305536c349264a46e04e23db87a675af156ae66f4baae1f9 languageName: node linkType: hard From 16cf0f7ff1f67b5be7bd4cc1defeee7745af9e9a Mon Sep 17 00:00:00 2001 From: Tamashoo <72484282+Tamashoo@users.noreply.github.com> Date: Sat, 29 Nov 2025 02:37:38 +0900 Subject: [PATCH 09/14] test(eslint-plugin): [consistent-type-exports] add more shadowed imports tests (#11766) * fix: consistent-type-exports handle shadowed import correctly * add re-export tests --------- Co-authored-by: Josh Goldberg --- .../fixtures/consistent-type-exports/reexport-1.ts | 1 + .../consistent-type-exports/reexport-2-named.ts | 3 +++ .../reexport-2-namespace.ts | 5 +++++ .../tests/rules/consistent-type-exports.test.ts | 14 ++++++++++++++ 4 files changed, 23 insertions(+) create mode 100644 packages/eslint-plugin/tests/fixtures/consistent-type-exports/reexport-1.ts create mode 100644 packages/eslint-plugin/tests/fixtures/consistent-type-exports/reexport-2-named.ts create mode 100644 packages/eslint-plugin/tests/fixtures/consistent-type-exports/reexport-2-namespace.ts diff --git a/packages/eslint-plugin/tests/fixtures/consistent-type-exports/reexport-1.ts b/packages/eslint-plugin/tests/fixtures/consistent-type-exports/reexport-1.ts new file mode 100644 index 000000000000..f29cc6f5296e --- /dev/null +++ b/packages/eslint-plugin/tests/fixtures/consistent-type-exports/reexport-1.ts @@ -0,0 +1 @@ +export type A = 1; diff --git a/packages/eslint-plugin/tests/fixtures/consistent-type-exports/reexport-2-named.ts b/packages/eslint-plugin/tests/fixtures/consistent-type-exports/reexport-2-named.ts new file mode 100644 index 000000000000..4486d9a3ab41 --- /dev/null +++ b/packages/eslint-plugin/tests/fixtures/consistent-type-exports/reexport-2-named.ts @@ -0,0 +1,3 @@ +import { A } from './reexport-1'; +const A = 1; +export { A }; diff --git a/packages/eslint-plugin/tests/fixtures/consistent-type-exports/reexport-2-namespace.ts b/packages/eslint-plugin/tests/fixtures/consistent-type-exports/reexport-2-namespace.ts new file mode 100644 index 000000000000..e422b217435c --- /dev/null +++ b/packages/eslint-plugin/tests/fixtures/consistent-type-exports/reexport-2-namespace.ts @@ -0,0 +1,5 @@ +import { A } from './reexport-1'; +namespace A { + export const b = 2; +} +export { A }; diff --git a/packages/eslint-plugin/tests/rules/consistent-type-exports.test.ts b/packages/eslint-plugin/tests/rules/consistent-type-exports.test.ts index 6863341b5b0f..de7aa6dff488 100644 --- a/packages/eslint-plugin/tests/rules/consistent-type-exports.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-type-exports.test.ts @@ -67,6 +67,20 @@ import { Type1 } from './consistent-type-exports'; const Type1 = 1; export { Type1 }; `, + ` +export { A } from './consistent-type-exports/reexport-2-named'; + `, + ` +import { A } from './consistent-type-exports/reexport-2-named'; +export { A }; + `, + ` +export { A } from './consistent-type-exports/reexport-2-namespace'; + `, + ` +import { A } from './consistent-type-exports/reexport-2-namespace'; +export { A }; + `, ], invalid: [ { From 906cc3c892cbd7cc929a797557a234f64e8bf539 Mon Sep 17 00:00:00 2001 From: SangheeSon Date: Sat, 29 Nov 2025 03:13:38 +0900 Subject: [PATCH 10/14] fix(eslint-plugin): [restrict-template-expressions] check base types in allow list (#11764) * fix(restrict-template-expressions): check base types in allow list Allow derived types in template expressions when base types are in allow list Fixes #11759 * fix: improve test coverage and fix import formatting * fix: improve test coverage and fix linting issues * chore: trigger CI rebuild * refactor: deduplicate base type checking logic - Remove unnecessary test comments - Extract hasBaseTypes to shared util - Create matchesTypeOrBaseType with matcher pattern * remove unnecessary test comments * add multiple inheritance tests * chore: retrigger CI --------- Co-authored-by: Josh Goldberg --- .../src/rules/no-base-to-string.ts | 50 ++---- .../rules/restrict-template-expressions.ts | 7 +- .../eslint-plugin/src/util/baseTypeUtils.ts | 68 ++++++++ packages/eslint-plugin/src/util/index.ts | 1 + .../restrict-template-expressions.test.ts | 152 ++++++++++++++++++ 5 files changed, 237 insertions(+), 41 deletions(-) create mode 100644 packages/eslint-plugin/src/util/baseTypeUtils.ts diff --git a/packages/eslint-plugin/src/rules/no-base-to-string.ts b/packages/eslint-plugin/src/rules/no-base-to-string.ts index 600f24fc7ce0..9f1953286115 100644 --- a/packages/eslint-plugin/src/rules/no-base-to-string.ts +++ b/packages/eslint-plugin/src/rules/no-base-to-string.ts @@ -9,6 +9,7 @@ import { getConstrainedTypeAtLocation, getParserServices, getTypeName, + matchesTypeOrBaseType, nullThrows, } from '../util'; @@ -77,7 +78,8 @@ export default createRule({ ], create(context, [option]) { const services = getParserServices(context); - const checker = services.program.getTypeChecker(); + const { program } = services; + const checker = program.getTypeChecker(); const ignoredTypeNames = option.ignoredTypeNames ?? []; function checkExpression(node: TSESTree.Expression, type?: ts.Type): void { @@ -211,44 +213,6 @@ export default createRule({ return Usefulness.Always; } - function getBaseTypesForType(type: ts.Type): readonly ts.Type[] { - if (!tsutils.isObjectType(type)) { - return []; - } - - const interfaceTarget = tsutils.isTypeReference(type) - ? type.target - : type; - - const interfaceType = - tsutils.isObjectFlagSet( - interfaceTarget, - ts.ObjectFlags.Interface | ts.ObjectFlags.Class, - ) && (interfaceTarget as ts.InterfaceType); - - if (!interfaceType) { - return []; - } - - return checker.getBaseTypes(interfaceType); - } - - function isIgnoredTypeOrBase( - type: ts.Type, - seen = new Set(), - ): boolean { - if (seen.has(type)) { - return false; - } - - seen.add(type); - - return ( - ignoredTypeNames.includes(getTypeName(checker, type)) || - getBaseTypesForType(type).some(base => isIgnoredTypeOrBase(base, seen)) - ); - } - function collectToStringCertainty( type: ts.Type, visited: Set, @@ -286,7 +250,13 @@ export default createRule({ return Usefulness.Always; } - if (isIgnoredTypeOrBase(type)) { + if ( + matchesTypeOrBaseType( + services, + type => ignoredTypeNames.includes(getTypeName(checker, type)), + type, + ) + ) { return Usefulness.Always; } diff --git a/packages/eslint-plugin/src/rules/restrict-template-expressions.ts b/packages/eslint-plugin/src/rules/restrict-template-expressions.ts index 069388b7eb0d..e2b6ba88b641 100644 --- a/packages/eslint-plugin/src/rules/restrict-template-expressions.ts +++ b/packages/eslint-plugin/src/rules/restrict-template-expressions.ts @@ -18,6 +18,7 @@ import { isTypeAnyType, isTypeFlagSet, isTypeNeverType, + matchesTypeOrBaseType, } from '../util'; type OptionTester = ( @@ -165,7 +166,11 @@ export default createRule({ return ( isTypeFlagSet(innerType, TypeFlags.StringLike) || - typeMatchesSomeSpecifier(innerType, allow, program) || + matchesTypeOrBaseType( + services, + type => typeMatchesSomeSpecifier(type, allow, program), + innerType, + ) || enabledOptionTesters.some(({ tester }) => tester(innerType, checker, recursivelyCheckType), ) diff --git a/packages/eslint-plugin/src/util/baseTypeUtils.ts b/packages/eslint-plugin/src/util/baseTypeUtils.ts new file mode 100644 index 000000000000..e06706b7fe35 --- /dev/null +++ b/packages/eslint-plugin/src/util/baseTypeUtils.ts @@ -0,0 +1,68 @@ +import type { ParserServicesWithTypeInformation } from '@typescript-eslint/utils'; +import type { InterfaceType, Type } from 'typescript'; + +import { isObjectFlagSet, isObjectType } from 'ts-api-utils'; +import * as tsutils from 'ts-api-utils'; +import * as ts from 'typescript'; + +function getBaseTypesForType( + checker: ts.TypeChecker, + type: ts.Type, +): readonly ts.Type[] { + if (!tsutils.isObjectType(type)) { + return []; + } + + const interfaceTarget = tsutils.isTypeReference(type) ? type.target : type; + + const interfaceType = + tsutils.isObjectFlagSet( + interfaceTarget, + ts.ObjectFlags.Interface | ts.ObjectFlags.Class, + ) && (interfaceTarget as ts.InterfaceType); + + if (!interfaceType) { + return []; + } + + return checker.getBaseTypes(interfaceType); +} + +export function hasBaseTypes(type: Type): type is InterfaceType { + return ( + isObjectType(type) && + isObjectFlagSet(type, ts.ObjectFlags.Interface | ts.ObjectFlags.Class) + ); +} + +/** + * Recursively checks if a type or any of its base types matches the provided + * matcher function. + * @param services Parser services with type information + * @param matcher Function to test if a type matches the desired criteria + * @param type The type to check + * @param seen Set of already visited types to prevent infinite recursion + * @returns `true` if the type or any of its base types match the matcher + */ +export function matchesTypeOrBaseType( + services: ParserServicesWithTypeInformation, + matcher: (type: Type) => boolean, + type: Type, + seen = new Set(), +): boolean { + if (seen.has(type)) { + return false; + } + + seen.add(type); + + if (matcher(type)) { + return true; + } + + const checker = services.program.getTypeChecker(); + + return getBaseTypesForType(checker, type).some(base => + matchesTypeOrBaseType(services, matcher, base, seen), + ); +} diff --git a/packages/eslint-plugin/src/util/index.ts b/packages/eslint-plugin/src/util/index.ts index 035fca0cec4a..6507d195d5f7 100644 --- a/packages/eslint-plugin/src/util/index.ts +++ b/packages/eslint-plugin/src/util/index.ts @@ -1,6 +1,7 @@ import { ESLintUtils } from '@typescript-eslint/utils'; export * from './astUtils'; +export * from './baseTypeUtils'; export * from './collectUnusedVariables'; export * from './createRule'; export * from './getFixOrSuggest'; diff --git a/packages/eslint-plugin/tests/rules/restrict-template-expressions.test.ts b/packages/eslint-plugin/tests/rules/restrict-template-expressions.test.ts index aa88c8276cdf..8b5aff9e940d 100644 --- a/packages/eslint-plugin/tests/rules/restrict-template-expressions.test.ts +++ b/packages/eslint-plugin/tests/rules/restrict-template-expressions.test.ts @@ -344,6 +344,102 @@ ruleTester.run('restrict-template-expressions', rule, { 'const msg = `arg = ${undefined}`;', 'const msg = `arg = ${123}`;', "const msg = `arg = ${'abc'}`;", + { + code: ` + class Base {} + class Derived extends Base {} + const foo = new Base(); + const bar = new Derived(); + \`\${foo}\${bar}\`; + `, + options: [{ allow: [{ from: 'file', name: 'Base' }] }], + }, + { + code: ` + class Base {} + class Derived extends Base {} + class DerivedTwice extends Derived {} + const value = new DerivedTwice(); + \`\${value}\`; + `, + options: [{ allow: [{ from: 'file', name: 'Base' }] }], + }, + { + code: ` + interface Base { + value: string; + } + interface Derived extends Base { + extra: number; + } + declare const obj: Derived; + \`\${obj}\`; + `, + options: [{ allow: [{ from: 'file', name: 'Base' }] }], + }, + { + code: ` + interface Base { + value: string; + } + interface Other { + other: number; + } + interface Derived extends Base, Other { + extra: boolean; + } + declare const obj: Derived; + \`\${obj}\`; + `, + options: [{ allow: [{ from: 'file', name: 'Base' }] }], + }, + { + code: ` + interface Base { + value: string; + } + interface Other { + other: number; + } + interface Derived extends Base, Other { + extra: boolean; + } + declare const obj: Derived; + \`\${obj}\`; + `, + options: [{ allow: [{ from: 'file', name: 'Other' }] }], + }, + { + code: ` + interface Root { + root: string; + } + interface Another { + another: string; + } + interface Base extends Root, Another { + value: string; + } + interface Other { + other: number; + } + interface Derived extends Base, Other { + extra: boolean; + } + declare const obj: Derived; + \`\${obj}\`; + `, + options: [{ allow: [{ from: 'file', name: 'Another' }] }], + }, + // allow list with type alias without base types + { + code: ` + type Custom = { value: string }; + declare const obj: Custom; + \`\${obj}\`; + `, + options: [{ allow: [{ from: 'file', name: 'Custom' }] }], + }, ], invalid: [ @@ -614,5 +710,61 @@ ruleTester.run('restrict-template-expressions', rule, { ], options: [{ allowAny: true }], }, + { + code: ` + class Base {} + class Derived extends Base {} + const bar = new Derived(); + \`\${bar}\`; + `, + errors: [ + { + data: { type: 'Derived' }, + messageId: 'invalidType', + }, + ], + options: [{ allow: [] }], + }, + { + code: ` + interface Base { + value: string; + } + interface Derived extends Base { + extra: number; + } + declare const obj: Derived; + \`\${obj}\`; + `, + errors: [ + { + data: { type: 'Derived' }, + messageId: 'invalidType', + }, + ], + options: [{ allow: [] }], + }, + { + code: ` + interface Base { + value: string; + } + interface Other { + other: number; + } + interface Derived extends Base, Other { + extra: boolean; + } + declare const obj: Derived; + \`\${obj}\`; + `, + errors: [ + { + data: { type: 'Derived' }, + messageId: 'invalidType', + }, + ], + options: [{ allow: [] }], + }, ], }); From ec8b6528819ff69c757fd1a8c1ca02f0f09c0830 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Mon, 1 Dec 2025 22:12:14 +0800 Subject: [PATCH 11/14] chore(typescript-estree): use class property to define `TSError.name` instead of `Object.defineProperty()` (#11776) chore: use class property to define `TSError.name` instead of `Object.defineProperty` --- packages/typescript-estree/src/node-utils.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/typescript-estree/src/node-utils.ts b/packages/typescript-estree/src/node-utils.ts index fb0349f7fbb3..908f892812dc 100644 --- a/packages/typescript-estree/src/node-utils.ts +++ b/packages/typescript-estree/src/node-utils.ts @@ -638,6 +638,8 @@ export function convertTokens(ast: ts.SourceFile): TSESTree.Token[] { } export class TSError extends Error { + override name = 'TSError'; + constructor( message: string, public readonly fileName: string, @@ -655,11 +657,6 @@ export class TSError extends Error { }, ) { super(message); - Object.defineProperty(this, 'name', { - configurable: true, - enumerable: false, - value: new.target.name, - }); } // For old version of ESLint https://github.com/typescript-eslint/typescript-eslint/pull/6556#discussion_r1123237311 From f8b2bb4d3571924185bd93b4967e786cc4886c21 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Mon, 1 Dec 2025 22:12:27 +0800 Subject: [PATCH 12/14] chore: check `VariableDeclaration` syntax error against tsNode (#11777) --- packages/typescript-estree/src/convert.ts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 952b6d30756a..b2281146fd5e 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -975,28 +975,27 @@ export class Converter { case SyntaxKind.VariableDeclaration: { const definite = !!node.exclamationToken; - const init = this.convertChild(node.initializer); - const id = this.convertBindingNameWithTypeAnnotation( - node.name, - node.type, - node, - ); + if (definite) { - if (init) { + if (node.initializer) { this.#throwError( node, 'Declarations with initializers cannot also have definite assignment assertions.', ); - } else if ( - id.type !== AST_NODE_TYPES.Identifier || - !id.typeAnnotation - ) { + } else if (node.name.kind !== SyntaxKind.Identifier || !node.type) { this.#throwError( node, 'Declarations with definite assignment assertions must also have type annotations.', ); } } + + const init = this.convertChild(node.initializer); + const id = this.convertBindingNameWithTypeAnnotation( + node.name, + node.type, + node, + ); return this.createNode(node, { type: AST_NODE_TYPES.VariableDeclarator, definite, From 5ac66a60cc4e391df78cb788054029ec9127c21c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josh=20Goldberg=20=E2=9C=A8?= Date: Mon, 1 Dec 2025 09:49:28 -0500 Subject: [PATCH 13/14] fix(eslint-plugin): revert "[no-redundant-type-constituents] use assignability checking for redundancy checks" (#11812) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Revert "feat(eslint-plugin): [no-redundant-type-constituents] use assignabili…" This reverts commit 2ffb1680d69fce4f08679c9c654a8a4ca463c64a. --- .../rules/no-redundant-type-constituents.ts | 942 ++++------ .../src/rules/no-unsafe-argument.ts | 2 +- .../src/rules/related-getter-setter-pairs.ts | 4 +- .../no-redundant-type-constituents.shot | 6 +- .../no-redundant-type-constituents.test.ts | 1641 +---------------- .../test-utils/serializers/TSESTreeNode.ts | 5 +- .../typescript-estree/src/parser-options.ts | 4 +- .../src/semantic-or-syntactic-errors.ts | 11 +- packages/utils/src/ts-eslint/Config.ts | 4 +- .../src/components/ast/DataRenderer.tsx | 3 +- .../src/components/hooks/useHashState.ts | 2 +- 11 files changed, 457 insertions(+), 2167 deletions(-) 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 0c1e2e27a813..2070ba9a869d 100644 --- a/packages/eslint-plugin/src/rules/no-redundant-type-constituents.ts +++ b/packages/eslint-plugin/src/rules/no-redundant-type-constituents.ts @@ -1,32 +1,76 @@ -import type { TSESTree } from '@typescript-eslint/utils'; - -import { AST_NODE_TYPES } from '@typescript-eslint/utils'; +import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; import { + arrayGroupByToMap, createRule, getParserServices, isFunctionOrFunctionType, + isTypeAnyType, + isTypeBigIntLiteralType, + isTypeNeverType, + isTypeTemplateLiteralType, + isTypeUnknownType, } from '../util'; +const literalToPrimitiveTypeFlags = { + [ts.TypeFlags.BigIntLiteral]: ts.TypeFlags.BigInt, + [ts.TypeFlags.BooleanLiteral]: ts.TypeFlags.Boolean, + [ts.TypeFlags.NumberLiteral]: ts.TypeFlags.Number, + [ts.TypeFlags.StringLiteral]: ts.TypeFlags.String, + [ts.TypeFlags.TemplateLiteral]: ts.TypeFlags.String, +} as const; + +const literalTypeFlags = [ + ts.TypeFlags.BigIntLiteral, + ts.TypeFlags.BooleanLiteral, + ts.TypeFlags.NumberLiteral, + ts.TypeFlags.StringLiteral, + ts.TypeFlags.TemplateLiteral, +] as const; + +const primitiveTypeFlags = [ + ts.TypeFlags.BigInt, + ts.TypeFlags.Boolean, + ts.TypeFlags.Number, + ts.TypeFlags.String, +] as const; + +const primitiveTypeFlagNames = { + [ts.TypeFlags.BigInt]: 'bigint', + [ts.TypeFlags.Boolean]: 'boolean', + [ts.TypeFlags.Number]: 'number', + [ts.TypeFlags.String]: 'string', +} as const; + +const primitiveTypeFlagTypes = { + bigint: ts.TypeFlags.BigIntLiteral, + boolean: ts.TypeFlags.BooleanLiteral, + number: ts.TypeFlags.NumberLiteral, + string: ts.TypeFlags.StringLiteral, +} as const; + +const keywordNodeTypesToTsTypes = new Map([ + [TSESTree.AST_NODE_TYPES.TSAnyKeyword, ts.TypeFlags.Any], + [TSESTree.AST_NODE_TYPES.TSBigIntKeyword, ts.TypeFlags.BigInt], + [TSESTree.AST_NODE_TYPES.TSBooleanKeyword, ts.TypeFlags.Boolean], + [TSESTree.AST_NODE_TYPES.TSNeverKeyword, ts.TypeFlags.Never], + [TSESTree.AST_NODE_TYPES.TSNumberKeyword, ts.TypeFlags.Number], + [TSESTree.AST_NODE_TYPES.TSStringKeyword, ts.TypeFlags.String], + [TSESTree.AST_NODE_TYPES.TSUnknownKeyword, ts.TypeFlags.Unknown], +]); + +type PrimitiveTypeFlag = (typeof primitiveTypeFlags)[number]; + interface TypeFlagsWithName { typeFlags: ts.TypeFlags; typeName: string; } -interface TypeWithName { - type: ts.Type; - typeName: string; -} - -interface TypeRedundancyRelation { - redundantTypeWithName: TypeWithName; - nonRedundantTypeWithName: TypeWithName; -} - -interface TypeWithNameAndParentNode extends TypeWithName { - parentTypeNode: TSESTree.TypeNode; +interface TypeNodeWithValue { + literalValue: unknown; + typeNode: TSESTree.TypeNode; } function addToMapGroup( @@ -43,395 +87,107 @@ function addToMapGroup( } } -function isUnionNodeInsideReturnType(node: TSESTree.TSUnionType): boolean { - if (node.parent.type === AST_NODE_TYPES.TSUnionType) { - return isUnionNodeInsideReturnType(node.parent); +function describeLiteralType(type: ts.Type): string { + if (type.isStringLiteral()) { + return JSON.stringify(type.value); } - return ( - node.parent.type === AST_NODE_TYPES.TSTypeAnnotation && - isFunctionOrFunctionType(node.parent.parent) - ); -} - -function isObjectOrIntersectionType( - type: ts.Type, -): type is ts.IntersectionType | ts.ObjectType { - return tsutils.isObjectType(type) || tsutils.isIntersectionType(type); -} -function shouldCheckTypeRedundancy( - type: ts.Type, - checker: ts.TypeChecker, - depth = 0, -): boolean { - if (depth > 10) { - return false; - } - if (tsutils.isObjectType(type)) { - const symbol = type.getSymbol(); - if (checker.isArrayLikeType(type)) { - return true; - } - if (!symbol) { - return false; - } - const declarations = symbol.getDeclarations(); - const declaration = declarations?.[0]; - if (!declaration) { - return false; - } - if ( - declaration.kind !== ts.SyntaxKind.TypeLiteral && - declaration.kind !== ts.SyntaxKind.InterfaceDeclaration && - declaration.kind !== ts.SyntaxKind.MappedType - ) { - return false; - } - } - if (isObjectOrIntersectionType(type)) { - const props = type.getProperties(); - for (const prop of props) { - const type = checker.getTypeOfSymbol(prop); - if (!shouldCheckTypeRedundancy(type, checker, depth + 1)) { - return false; - } - } - return true; - } - if (tsutils.isUnionType(type)) { - return type.types.every(typePart => - shouldCheckTypeRedundancy(typePart, checker, depth), - ); + if (isTypeBigIntLiteralType(type)) { + return `${type.value.negative ? '-' : ''}${type.value.base10Value}n`; } - return true; -} -function isTargetTypeRedundantInIntersection( - sourceType: ts.Type, - targetType: ts.Type, - checker: ts.TypeChecker, -): boolean { - if ( - !shouldCheckTypeRedundancy(sourceType, checker) || - !shouldCheckTypeRedundancy(targetType, checker) - ) { - return false; - } - if (tsutils.isUnionType(sourceType)) { - for (const typePart of sourceType.types) { - if (!tsutils.isObjectType(typePart)) { - continue; - } - const isRedundant = isTargetTypeRedundantInIntersection( - typePart, - targetType, - checker, - ); - if (!isRedundant) { - return false; - } - } - return checker.isTypeAssignableTo(sourceType, targetType); + if (type.isLiteral()) { + // eslint-disable-next-line @typescript-eslint/no-base-to-string + return type.value.toString(); } - if ( - tsutils.isUnionType(targetType) && - !tsutils.isIntrinsicBooleanType(targetType) - ) { - for (const typePart of targetType.types) { - if (!tsutils.isObjectType(typePart)) { - continue; - } - const isRedundant = isTargetTypeRedundantInIntersection( - sourceType, - typePart, - checker, - ); - if (!isRedundant) { - return false; - } - } - return checker.isTypeAssignableTo(sourceType, targetType); + if (tsutils.isIntrinsicErrorType(type) && type.aliasSymbol) { + return type.aliasSymbol.escapedName.toString(); } - if (checker.isTupleType(targetType)) { - if (checker.isTupleType(sourceType)) { - const sourceArguments = sourceType.typeArguments; - const targetArguments = targetType.typeArguments; - - if (!sourceArguments || !targetArguments) { - return false; - } - if (targetArguments.length !== sourceArguments.length) { - return false; - } - for (let i = 0; i < targetArguments.length; ++i) { - const sourceTypeArgument = sourceArguments[i]; - const targetTypeArgument = targetArguments[i]; - if ( - !isTargetTypeRedundantInIntersection( - sourceTypeArgument, - targetTypeArgument, - checker, - ) - ) { - return false; - } - } - return true; - } - return false; + if (isTypeAnyType(type)) { + return 'any'; } - if (checker.isArrayType(targetType)) { - if (checker.isArrayType(sourceType)) { - const sourceArgumentType = sourceType.typeArguments?.[0]; - const targetArgumentType = targetType.typeArguments?.[0]; - - if (!sourceArgumentType || !targetArgumentType) { - return false; - } - return isTargetTypeRedundantInIntersection( - sourceArgumentType, - targetArgumentType, - checker, - ); - } - if (checker.isTupleType(sourceType)) { - const targetArgumentType = targetType.typeArguments?.[0]; - if (!targetArgumentType) { - return false; - } - const sourceArgumentTypes = sourceType.typeArguments; - if (!sourceArgumentTypes) { - return true; - } - for (const sourceTypeArgument of sourceArgumentTypes) { - if ( - !isTargetTypeRedundantInIntersection( - sourceTypeArgument, - targetArgumentType, - checker, - ) - ) { - return false; - } - } - return true; - } - return false; + if (isTypeNeverType(type)) { + return 'never'; } - if (tsutils.isObjectType(sourceType) && tsutils.isObjectType(targetType)) { - const sourceProps = sourceType.getProperties(); - const targetProps = targetType.getProperties(); - if (targetProps.length === 0) { - return false; - } - for (const targetProp of targetProps) { - const sourceProp = sourceProps.find( - prop => prop.getName() === targetProp.getName(), - ); - - if (!sourceProp) { - return false; - } - - const sourcePropType = checker.getTypeOfSymbol(sourceProp); - const targetPropType = checker.getTypeOfSymbol(targetProp); - - const targetPropTypeIsRedundant = isTargetTypeRedundantInIntersection( - sourcePropType, - targetPropType, - checker, - ); - if (!targetPropTypeIsRedundant) { - return false; - } - } - return true; + if (isTypeUnknownType(type)) { + return 'unknown'; } - return checker.isTypeAssignableTo(sourceType, targetType); -} -function isTargetTypeRedundantInUnion( - sourceType: ts.Type, - targetType: ts.Type, - checker: ts.TypeChecker, -): boolean { - if ( - !shouldCheckTypeRedundancy(sourceType, checker) || - !shouldCheckTypeRedundancy(targetType, checker) - ) { - return false; - } - if ( - tsutils.isUnionType(targetType) && - !tsutils.isIntrinsicBooleanType(targetType) - ) { - for (const typePart of targetType.types) { - const isRedundant = isTargetTypeRedundantInUnion( - sourceType, - typePart, - checker, - ); - if (!isRedundant) { - return false; - } - } - return true; - } - if (tsutils.isUnionType(sourceType)) { - for (const typePart of sourceType.types) { - const isRedundant = isTargetTypeRedundantInUnion( - typePart, - targetType, - checker, - ); - if (isRedundant) { - return true; - } - } - return false; + if (isTypeTemplateLiteralType(type)) { + return 'template literal type'; } - if (checker.isTupleType(targetType)) { - if (checker.isArrayType(sourceType)) { - const sourceArgumentType = sourceType.typeArguments?.[0]; - if (!sourceArgumentType) { - return false; - } - const targetArguments = targetType.typeArguments; - if (!targetArguments) { - return true; - } - for (const targetTypeArgument of targetArguments) { - if ( - !isTargetTypeRedundantInUnion( - sourceArgumentType, - targetTypeArgument, - checker, - ) - ) { - return false; - } - } - return true; - } - if (checker.isTupleType(sourceType)) { - const sourceArguments = sourceType.typeArguments; - const targetArguments = targetType.typeArguments; - - if (!sourceArguments || !targetArguments) { - return false; - } - if (targetArguments.length !== sourceArguments.length) { - return false; - } - for (let i = 0; i < targetArguments.length; ++i) { - const sourceTypeArgument = sourceArguments[i]; - const targetTypeArgument = targetArguments[i]; - if ( - !isTargetTypeRedundantInUnion( - sourceTypeArgument, - targetTypeArgument, - checker, - ) - ) { - return false; - } - } - return true; - } - return false; + if (isTypeBigIntLiteralType(type)) { + return `${type.value.negative ? '-' : ''}${type.value.base10Value}n`; } - if (checker.isArrayType(sourceType) && checker.isArrayType(targetType)) { - const sourceArgumentType = sourceType.typeArguments?.[0]; - const targetArgumentType = targetType.typeArguments?.[0]; - - if (!sourceArgumentType || !targetArgumentType) { - return false; - } - return isTargetTypeRedundantInUnion( - sourceArgumentType, - targetArgumentType, - checker, - ); + if (tsutils.isTrueLiteralType(type)) { + return 'true'; } - if ( - isObjectOrIntersectionType(sourceType) && - isObjectOrIntersectionType(targetType) - ) { - const sourceProps = sourceType.getProperties(); - const targetProps = targetType.getProperties(); - - if (sourceProps.length !== targetProps.length) { - return false; - } - if (targetProps.length === 0) { - return false; - } - for (const targetProp of targetProps) { - const sourceProp = sourceProps.find( - prop => prop.getName() === targetProp.getName(), - ); - - if (!sourceProp) { - return false; - } + if (tsutils.isFalseLiteralType(type)) { + return 'false'; + } - const sourcePropType = checker.getTypeOfSymbol(sourceProp); - const targetPropType = checker.getTypeOfSymbol(targetProp); + return 'literal type'; +} - const targetPropTypeIsRedundant = isTargetTypeRedundantInUnion( - sourcePropType, - targetPropType, - checker, - ); - if (!targetPropTypeIsRedundant) { - return false; +function describeLiteralTypeNode(typeNode: TSESTree.TypeNode): string { + switch (typeNode.type) { + case AST_NODE_TYPES.TSAnyKeyword: + return 'any'; + case AST_NODE_TYPES.TSBooleanKeyword: + return 'boolean'; + case AST_NODE_TYPES.TSNeverKeyword: + return 'never'; + case AST_NODE_TYPES.TSNumberKeyword: + return 'number'; + case AST_NODE_TYPES.TSStringKeyword: + return 'string'; + case AST_NODE_TYPES.TSUnknownKeyword: + return 'unknown'; + case AST_NODE_TYPES.TSLiteralType: + switch (typeNode.literal.type) { + case TSESTree.AST_NODE_TYPES.Literal: + switch (typeof typeNode.literal.value) { + case 'bigint': + return `${typeNode.literal.value < 0 ? '-' : ''}${ + typeNode.literal.value + }n`; + case 'string': + return JSON.stringify(typeNode.literal.value); + default: + return `${typeNode.literal.value}`; + } + case TSESTree.AST_NODE_TYPES.TemplateLiteral: + return 'template literal type'; } - } - return true; - } - return checker.isTypeAssignableTo(targetType, sourceType); -} -function mergeTypeNames( - typeWithNames: TypeWithName[], - operator: '&' | '|', -): string { - if (typeWithNames.length === 1) { - return typeWithNames[0].typeName; } - const wrapType = (typeWithName: TypeWithName) => { - if (operator === '|' && typeWithName.type.isIntersection()) { - return `(${typeWithName.typeName})`; - } - if (operator === '&' && typeWithName.type.isUnion()) { - return `(${typeWithName.typeName})`; - } - return typeWithName.typeName; - }; + return 'literal type'; +} - return typeWithNames.map(wrapType).join(` ${operator} `); +function isNodeInsideReturnType(node: TSESTree.TSUnionType): boolean { + return ( + node.parent.type === AST_NODE_TYPES.TSTypeAnnotation && + isFunctionOrFunctionType(node.parent.parent) + ); } -function getGroupTypeRelationsByNonRedundantType( - typeRedundancyRelations: TypeRedundancyRelation[], -) { - const groups = new Map(); - - for (const typeRedundancyRelation of typeRedundancyRelations) { - addToMapGroup( - groups, - typeRedundancyRelation.nonRedundantTypeWithName.type, - typeRedundancyRelation, - ); - } - return groups; +/** + * @remarks TypeScript stores boolean types as the union false | true, always. + */ +function unionTypePartsUnlessBoolean(type: ts.Type): ts.Type[] { + return type.isUnion() && + type.types.length === 2 && + tsutils.isFalseLiteralType(type.types[0]) && + tsutils.isTrueLiteralType(type.types[1]) + ? [type] + : tsutils.unionConstituents(type); } export default createRule({ @@ -446,102 +202,83 @@ export default createRule({ }, messages: { errorTypeOverrides: `'{{typeName}}' is an 'error' type that acts as 'any' and overrides all other types in this {{container}} type.`, + literalOverridden: `{{literal}} is overridden by {{primitive}} in this union type.`, overridden: `'{{typeName}}' is overridden by other types in this {{container}} type.`, overrides: `'{{typeName}}' overrides all other types in this {{container}} type.`, - typeOverridden: `{{redundantType}} is overridden by {{nonRedundantType}} in this {{container}} type.`, + primitiveOverridden: `{{primitive}} is overridden by the {{literal}} in this intersection type.`, }, schema: [], }, defaultOptions: [], create(context) { const services = getParserServices(context); - const checker = services.program.getTypeChecker(); - - function reportRedundantTypes( - redundantTypes: Map, - container: 'intersection' | 'union', - ) { - for (const [typeNode, typeRelations] of redundantTypes) { - const groupTypeRelationsByNonRedundantType = - getGroupTypeRelationsByNonRedundantType(typeRelations); - - for (const [ - nonRedundantType, - typeRelationAndNames, - ] of groupTypeRelationsByNonRedundantType) { - const nonRedundantTypeName = checker.typeToString(nonRedundantType); - const mergedRedundantTypeName = mergeTypeNames( - typeRelationAndNames.map( - ({ redundantTypeWithName }) => redundantTypeWithName, - ), - container === 'union' ? '|' : '&', - ); - - context.report({ - node: typeNode, - messageId: 'typeOverridden', - data: { - container, - nonRedundantType: nonRedundantTypeName, - redundantType: mergedRedundantTypeName, - }, - }); - } + const typesCache = new Map(); + + function getTypeNodeTypePartFlags( + typeNode: TSESTree.TypeNode, + ): TypeFlagsWithName[] { + const keywordTypeFlags = keywordNodeTypesToTsTypes.get(typeNode.type); + if (keywordTypeFlags) { + return [ + { + typeFlags: keywordTypeFlags, + typeName: describeLiteralTypeNode(typeNode), + }, + ]; } - } - function getUnionTypePart( - typeNode: ts.Node, - checker: ts.TypeChecker, - ): TypeWithName[] { - if (ts.isParenthesizedTypeNode(typeNode)) { - return getUnionTypePart(typeNode.type, checker); - } - if (ts.isUnionTypeNode(typeNode)) { - return typeNode.types.flatMap(typeNode => - getUnionTypePart(typeNode, checker), - ); + if ( + typeNode.type === AST_NODE_TYPES.TSLiteralType && + typeNode.literal.type === AST_NODE_TYPES.Literal + ) { + return [ + { + typeFlags: + primitiveTypeFlagTypes[ + typeof typeNode.literal + .value as keyof typeof primitiveTypeFlagTypes + ], + typeName: describeLiteralTypeNode(typeNode), + }, + ]; } - const type = checker.getTypeAtLocation(typeNode); - - return [ - { - type, - typeName: checker.typeToString(type), - }, - ]; - } - function getIntersectionTypePart( - typeNode: ts.Node, - checker: ts.TypeChecker, - ): TypeWithName[] { - if (ts.isParenthesizedTypeNode(typeNode)) { - return getIntersectionTypePart(typeNode.type, checker); + if (typeNode.type === AST_NODE_TYPES.TSUnionType) { + return typeNode.types.flatMap(getTypeNodeTypePartFlags); } - if (ts.isIntersectionTypeNode(typeNode)) { - return typeNode.types.flatMap(typeNode => - getIntersectionTypePart(typeNode, checker), - ); - } + const nodeType = services.getTypeAtLocation(typeNode); + const typeParts = unionTypePartsUnlessBoolean(nodeType); - const type = checker.getTypeAtLocation(typeNode); + return typeParts.map(typePart => ({ + typeFlags: typePart.flags, + typeName: describeLiteralType(typePart), + })); + } + + function getTypeNodeTypePartFlagsCached( + typeNode: TSESTree.TypeNode, + ): TypeFlagsWithName[] { + const existing = typesCache.get(typeNode); + if (existing) { + return existing; + } - return [ - { - type, - typeName: checker.typeToString(type), - }, - ]; + const created = getTypeNodeTypePartFlags(typeNode); + typesCache.set(typeNode, created); + return created; } return { - TSIntersectionType(node: TSESTree.TSIntersectionType): void { - const seenTypes = new Set(); - const redundantTypes = new Map< + 'TSIntersectionType:exit'(node: TSESTree.TSIntersectionType): void { + const seenLiteralTypes = new Map(); + const seenPrimitiveTypes = new Map< + PrimitiveTypeFlag, + TSESTree.TypeNode[] + >(); + const seenUnionTypes = new Map< TSESTree.TypeNode, - TypeRedundancyRelation[] + TypeFlagsWithName[] >(); function checkIntersectionBottomAndTopTypes( @@ -573,97 +310,107 @@ export default createRule({ } for (const typeNode of node.types) { - const tsTypeNode = services.esTreeNodeToTSNodeMap.get(typeNode); - const typeParts = getIntersectionTypePart(tsTypeNode, checker); - - for (const typePart of typeParts) { - if ( - typePart.type.flags & ts.TypeFlags.Never || - typePart.type.flags & ts.TypeFlags.Any || - typePart.type.flags & ts.TypeFlags.Unknown - ) { - checkIntersectionBottomAndTopTypes( - { - typeFlags: typePart.type.flags, - typeName: typePart.typeName, - }, - typeNode, - ); + const typePartFlags = getTypeNodeTypePartFlagsCached(typeNode); + + for (const typePart of typePartFlags) { + if (checkIntersectionBottomAndTopTypes(typePart, typeNode)) { continue; } - const { type: targetType, typeName: targetTypeName } = typePart; - - for (const seenType of seenTypes) { - const { - type: sourceType, - parentTypeNode, - typeName: sourceTypeName, - } = seenType; - const targetTypeIsRedundant = isTargetTypeRedundantInIntersection( - sourceType, - targetType, - checker, - ); - const sourceTypeIsRedundant = isTargetTypeRedundantInIntersection( - targetType, - sourceType, - checker, - ); - if ( - targetTypeIsRedundant && - targetTypeIsRedundant === sourceTypeIsRedundant - ) { - continue; + + for (const literalTypeFlag of literalTypeFlags) { + if (typePart.typeFlags === literalTypeFlag) { + addToMapGroup( + seenLiteralTypes, + literalToPrimitiveTypeFlags[literalTypeFlag], + typePart.typeName, + ); + break; } - if (sourceTypeIsRedundant) { - addToMapGroup(redundantTypes, parentTypeNode, { - nonRedundantTypeWithName: { - type: targetType, - typeName: targetTypeName, - }, - redundantTypeWithName: { - type: sourceType, - typeName: sourceTypeName, - }, - }); + } + + for (const primitiveTypeFlag of primitiveTypeFlags) { + if (typePart.typeFlags === primitiveTypeFlag) { + addToMapGroup(seenPrimitiveTypes, primitiveTypeFlag, typeNode); } - if (targetTypeIsRedundant) { - addToMapGroup(redundantTypes, typeNode, { - nonRedundantTypeWithName: { - type: sourceType, - typeName: sourceTypeName, - }, - redundantTypeWithName: { - type: targetType, - typeName: targetTypeName, - }, - }); + } + } + // if any typeNode is TSTypeReference and typePartFlags have more than 1 element, than the referenced type is definitely a union. + if (typePartFlags.length >= 2) { + seenUnionTypes.set(typeNode, typePartFlags); + } + } + /** + * @example + * ```ts + * type F = "a"|2|"b"; + * type I = F & string; + * ``` + * This function checks if all the union members of `F` are assignable to the other member of `I`. If every member is assignable, then its reported else not. + */ + const checkIfUnionsAreAssignable = (): undefined => { + for (const [typeRef, typeValues] of seenUnionTypes) { + let primitive: number | undefined = undefined; + for (const { typeFlags } of typeValues) { + if ( + seenPrimitiveTypes.has( + literalToPrimitiveTypeFlags[ + typeFlags as keyof typeof literalToPrimitiveTypeFlags + ], + ) + ) { + primitive = + literalToPrimitiveTypeFlags[ + typeFlags as keyof typeof literalToPrimitiveTypeFlags + ]; + } else { + primitive = undefined; + break; } } + if (Number.isInteger(primitive)) { + context.report({ + node: typeRef, + messageId: 'primitiveOverridden', + data: { + literal: typeValues.map(name => name.typeName).join(' | '), + primitive: + primitiveTypeFlagNames[ + primitive as keyof typeof primitiveTypeFlagNames + ], + }, + }); + } } - for (const typePart of typeParts) { - if ( - typePart.type.flags === ts.TypeFlags.Any || - typePart.type.flags === ts.TypeFlags.Unknown || - typePart.type.flags === ts.TypeFlags.Never - ) { - continue; + }; + if (seenUnionTypes.size > 0) { + checkIfUnionsAreAssignable(); + return; + } + // For each primitive type of all the seen primitive types, + // if there was a literal type seen that overrides it, + // report each of the primitive type's type nodes + for (const [primitiveTypeFlag, typeNodes] of seenPrimitiveTypes) { + const matchedLiteralTypes = seenLiteralTypes.get(primitiveTypeFlag); + if (matchedLiteralTypes) { + for (const typeNode of typeNodes) { + context.report({ + node: typeNode, + messageId: 'primitiveOverridden', + data: { + literal: matchedLiteralTypes.join(' | '), + primitive: primitiveTypeFlagNames[primitiveTypeFlag], + }, + }); } - - seenTypes.add({ - ...typePart, - parentTypeNode: typeNode, - }); } } - reportRedundantTypes(redundantTypes, 'intersection'); }, - TSUnionType(node: TSESTree.TSUnionType): void { - const seenTypes = new Set(); - const redundantTypes = new Map< - TSESTree.TypeNode, - TypeRedundancyRelation[] + 'TSUnionType:exit'(node: TSESTree.TSUnionType): void { + const seenLiteralTypes = new Map< + PrimitiveTypeFlag, + TypeNodeWithValue[] >(); + const seenPrimitiveTypes = new Set(); function checkUnionBottomAndTopTypes( { typeFlags, typeName }: TypeFlagsWithName, @@ -691,7 +438,7 @@ export default createRule({ if ( typeFlags === ts.TypeFlags.Never && - !isUnionNodeInsideReturnType(node) + !isNodeInsideReturnType(node) ) { context.report({ node: typeNode, @@ -708,90 +455,79 @@ export default createRule({ } for (const typeNode of node.types) { - const tsTypeNode = services.esTreeNodeToTSNodeMap.get(typeNode); - const typeParts = getUnionTypePart(tsTypeNode, checker); - for (const typePart of typeParts) { - if ( - typePart.type.flags & ts.TypeFlags.Never || - typePart.type.flags & ts.TypeFlags.Any || - typePart.type.flags & ts.TypeFlags.Unknown - ) { - checkUnionBottomAndTopTypes( - { - typeFlags: typePart.type.flags, - typeName: typePart.typeName, - }, - typeNode, - ); + const typePartFlags = getTypeNodeTypePartFlagsCached(typeNode); + + for (const typePart of typePartFlags) { + if (checkUnionBottomAndTopTypes(typePart, typeNode)) { continue; } - const { type: targetType, typeName: targetTypeName } = typePart; - for (const seenType of seenTypes) { - const { - type: sourceType, - parentTypeNode, - typeName: sourceTypeName, - } = seenType; - const targetTypeIsRedundant = isTargetTypeRedundantInUnion( - sourceType, - targetType, - checker, - ); - const sourceTypeIsRedundant = isTargetTypeRedundantInUnion( - targetType, - sourceType, - checker, - ); - if ( - targetTypeIsRedundant && - targetTypeIsRedundant === sourceTypeIsRedundant - ) { - continue; - } - if (sourceTypeIsRedundant) { - addToMapGroup(redundantTypes, parentTypeNode, { - nonRedundantTypeWithName: { - type: targetType, - typeName: targetTypeName, - }, - redundantTypeWithName: { - type: sourceType, - typeName: sourceTypeName, + for (const literalTypeFlag of literalTypeFlags) { + if (typePart.typeFlags === literalTypeFlag) { + addToMapGroup( + seenLiteralTypes, + literalToPrimitiveTypeFlags[literalTypeFlag], + { + literalValue: typePart.typeName, + typeNode, }, - }); + ); + break; } - if (targetTypeIsRedundant) { - addToMapGroup(redundantTypes, typeNode, { - nonRedundantTypeWithName: { - type: sourceType, - typeName: sourceTypeName, - }, - redundantTypeWithName: { - type: targetType, - typeName: targetTypeName, - }, - }); + } + + for (const primitiveTypeFlag of primitiveTypeFlags) { + if ((typePart.typeFlags & primitiveTypeFlag) !== 0) { + seenPrimitiveTypes.add(primitiveTypeFlag); } } } + } - for (const typePart of typeParts) { - if ( - typePart.type.flags === ts.TypeFlags.Any || - typePart.type.flags === ts.TypeFlags.Unknown || - typePart.type.flags === ts.TypeFlags.Never - ) { - continue; + interface TypeFlagWithText { + literalValue: unknown; + primitiveTypeFlag: PrimitiveTypeFlag; + } + + const overriddenTypeNodes = new Map< + TSESTree.TypeNode, + TypeFlagWithText[] + >(); + + // For each primitive type of all the seen literal types, + // if there was a primitive type seen that overrides it, + // upsert the literal text and primitive type under the backing type node + for (const [primitiveTypeFlag, typeNodesWithText] of seenLiteralTypes) { + if (seenPrimitiveTypes.has(primitiveTypeFlag)) { + for (const { literalValue, typeNode } of typeNodesWithText) { + addToMapGroup(overriddenTypeNodes, typeNode, { + literalValue, + primitiveTypeFlag, + }); } - seenTypes.add({ - ...typePart, - parentTypeNode: typeNode, - }); } } - reportRedundantTypes(redundantTypes, 'union'); + // For each type node that had at least one overridden literal, + // group those literals by their primitive type, + // then report each primitive type with all its literals + for (const [typeNode, typeFlagsWithText] of overriddenTypeNodes) { + const grouped = arrayGroupByToMap( + typeFlagsWithText, + pair => pair.primitiveTypeFlag, + ); + + for (const [primitiveTypeFlag, pairs] of grouped) { + context.report({ + node: typeNode, + messageId: 'literalOverridden', + data: { + literal: pairs.map(pair => pair.literalValue).join(' | '), + primitive: primitiveTypeFlagNames[primitiveTypeFlag], + }, + }); + } + } }, }; }, diff --git a/packages/eslint-plugin/src/rules/no-unsafe-argument.ts b/packages/eslint-plugin/src/rules/no-unsafe-argument.ts index d7087988cb30..4ae7f4bcc28b 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-argument.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-argument.ts @@ -193,7 +193,7 @@ export default createRule<[], MessageIds>({ } function checkUnsafeArguments( - args: TSESTree.CallExpressionArgument[], + args: TSESTree.CallExpressionArgument[] | TSESTree.Expression[], callee: TSESTree.Expression, node: | TSESTree.CallExpression diff --git a/packages/eslint-plugin/src/rules/related-getter-setter-pairs.ts b/packages/eslint-plugin/src/rules/related-getter-setter-pairs.ts index 1b052ca4a792..89019b1d0a03 100644 --- a/packages/eslint-plugin/src/rules/related-getter-setter-pairs.ts +++ b/packages/eslint-plugin/src/rules/related-getter-setter-pairs.ts @@ -11,7 +11,9 @@ type GetMethod = { returnType: TSESTree.TSTypeAnnotation; } & Method; -type GetMethodRaw = GetMethod; +type GetMethodRaw = { + returnType: TSESTree.TSTypeAnnotation | undefined; +} & GetMethod; type SetMethod = { kind: 'set'; params: [TSESTree.Node] } & Method; diff --git a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/no-redundant-type-constituents.shot b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/no-redundant-type-constituents.shot index c194fd0da174..f6fb194487d8 100644 --- a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/no-redundant-type-constituents.shot +++ b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/no-redundant-type-constituents.shot @@ -22,11 +22,11 @@ type IntersectionNever = string | never; ~~~~~ 'never' is overridden by other types in this union type. type IntersectionBooleanLiteral = boolean & false; - ~~~~~~~ boolean is overridden by false in this intersection type. + ~~~~~~~ boolean is overridden by the false in this intersection type. type IntersectionNumberLiteral = number & 1; - ~~~~~~ number is overridden by 1 in this intersection type. + ~~~~~~ number is overridden by the 1 in this intersection type. type IntersectionStringLiteral = string & 'foo'; - ~~~~~~ string is overridden by "foo" in this intersection type. + ~~~~~~ string is overridden by the "foo" in this intersection type. Correct diff --git a/packages/eslint-plugin/tests/rules/no-redundant-type-constituents.test.ts b/packages/eslint-plugin/tests/rules/no-redundant-type-constituents.test.ts index 8b6ff31b62c9..ce51eb308044 100644 --- a/packages/eslint-plugin/tests/rules/no-redundant-type-constituents.test.ts +++ b/packages/eslint-plugin/tests/rules/no-redundant-type-constituents.test.ts @@ -156,132 +156,8 @@ ruleTester.run('no-redundant-type-constituents', rule, { type U = T & string; `, "declare function fn(): never | 'foo';", - "declare function fn(): (never | 'foo') | 123;", - "declare function fn(): ((never | 4) | 'foo') | 123;", - 'type Foo = { a: string } | { a: number };', - "type Foo = { a: string } | { a: 'b' | 'c' | 0 };", - "type Foo = { a: 'b' | 'c' | 0 } | ({ a: 1 } | { a: 'a' });", - 'type Foo = { a: 1 } | { a: 1; b: 1 };', - 'type Foo = { a: 1 } | ({ a: 1 } & { b: 1 });', - 'type Foo = ({ a: 1 } & { b: 1 }) | { a: 1 };', - 'type Foo = { a: 1 } & { b: number };', - 'type Foo = { a: 1; b: 1 } & ({ a: 1; b: 1; c: 1 } | { a: 1 });', - 'type Foo = ({ a: 1; b: 1; c: 1 } | { a: 1 }) & { a: 1; b: 1 };', - ` - type Foo = - | (({ a: 1 } | { b: 1 }) & { a: 1 }) - | (({ a: 1 } | { c: 1 }) & { a: 1 }); - `, - 'type Foo = { a: 1 } | { a: { a: 1 } };', - 'type T = { [key: string]: 1 } | { a: 1 };', - 'type T = Partial<{ a: 1; b: 1 }> | { a: 1 };', - "type T = Omit<{ a: 1; b: 1 }, 'a'> | { a: number; b: number };", - 'type T = { a?: 1; b?: 1 } & { a: 1 };', - "type F = Omit & { a: 1 };", - "type F = Omit & { a?: 1 };", - "type F = Omit & { a?: 1; b?: 1 };", - "type F = Omit & { a?: 1; b: 1 };", - 'type T = { a: { b: 1 } } & { a: { b: { c: 1 } } };', - ` - interface A { - a: 1; - } - interface B extends A { - b: 1; - } - type C = A | B; - `, - 'type T = { a: { b: 1 }; c: { d: 1 } } | { a: { b: 1 }; c: { d: 1; a: 1 } };', - 'type T = Record & { a: 1 };', - 'type T = { [key: string]: 1 } & { a: 1 };', - ` - type T = { [key: string]: 1 }; - type U = T & { a: 1 }; - `, - ` - type T = { a: 1; b: 1 }; - type U = Omit & Required; - type K = U<'a'>; - type R = K | { a: 1 }; - `, - "type T = (() => string) | (() => '123');", - "type T = (() => string) & (() => '123');", - 'type T = (() => { a: 1; b: 1 }) & (() => { a: 1 });', - 'type T = (() => { a: 1; b: 1 }) | (() => { a: 1 });', - ` - class A { - a: string; - } - class B { - a: '132'; - } - type T = A | B; - `, - ` - class A { - a: string; - } - class B { - a: '132'; - } - type T = A & B; - `, - ` - interface A { - a: 1; - m(): string; - } - interface B { - a: 1; - m(): '123'; - } - type T = A & B; - `, - "type T = { a: { b: () => string } } | { a: { b: () => '123' } };", - "type T = { a: { b: () => string } } & { a: { b: () => '123' } };", - "type T = (() => '123') & (() => string);", - "type T = (() => '123') | (() => string);", - 'type T = { a: 1 | { a: 1; b: 1 } } | { a: 1 | { b: 1 } };', - 'type T = { a: 1 | 3 | (() => void) } | { a: 1 | 3 | 5 };', - 'type T = { a: 1 | 3 | { c: 1 } } & { a: 1 | { b: 1 } };', - 'type T = { a: 1 | 3 | { b: 1; c: 1 } } & { a: 1 | { b: 1 } };', - 'type T = { a: 1 | 3 | { c: 1 } | (() => void) } & { a: 1 | { b: 1 } };', - "type T = { a: '1' | { b: 1 } } & { a: 1 | { b: 1 } };", - 'type T = { a: { c: 1 } | { b: 1 } } & { a: { b: 1 } };', - 'type T = { a: { c: 1 } | { a?: 1; b: 1 } } & { a: { b: 1 } | { a?: 1; b: 1 } };', - 'type T = { a: { d: number } | { b: number } } & { a: { b: 1 } | { d: 1 } };', - ` - type Node = { - value: string; - next?: Node; - }; - type T = Node & { next: Node }; - `, - ` - type Node = { - value: string; - next: Node; - }; - type T = Node | { next: Node }; - `, - ` - type R = { a: 1 } | { a: 4 }; - type T = { a: 1 | 2 } | { a: 3 }; - type U = R | T; - `, - 'type T = [1, 2] | [1];', - 'type T = [1, 2, 3] | [1, 2, 4];', - 'type T = [] | [1];', - 'type T = Array | Array;', - 'type T = Array | string[];', - 'type T = [1, 2, 3] | [1, 2, 3, 4];', - 'type T = [{ a: 1 }] | [{ a: 1; b: 1 }];', - 'type T = [{ a: number }] | [{ a: 1; b: 1 }];', - 'type T = [1, 2] & [1];', - 'type T = Array & [1];', - 'type T = Array & Array;', - 'type T = Array & string[];', ], + invalid: [ { code: 'type T = number | any;', @@ -444,11 +320,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 19, data: { - container: 'union', - nonRedundantType: 'number', - redundantType: '0', + literal: '0', + primitive: 'number', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -458,11 +333,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 20, data: { - container: 'union', - nonRedundantType: 'number', - redundantType: '0 | 1', + literal: '0 | 1', + primitive: 'number', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -472,11 +346,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 11, data: { - container: 'union', - nonRedundantType: 'number', - redundantType: '0 | 0', + literal: '0 | 0', + primitive: 'number', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -489,11 +362,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 19, data: { - container: 'union', - nonRedundantType: 'number', - redundantType: '2 | B', + literal: '2 | 0 | 1', + primitive: 'number', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -503,11 +375,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 11, data: { - container: 'union', - nonRedundantType: 'number', - redundantType: '0 | 1 | 2', + literal: '0 | 1 | 2', + primitive: 'number', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -517,11 +388,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 11, data: { - container: 'union', - nonRedundantType: 'number', - redundantType: '0 | 1', + literal: '0 | 1', + primitive: 'number', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -531,11 +401,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 11, data: { - container: 'union', - nonRedundantType: 'number', - redundantType: '0 | 0 | 1', + literal: '0 | 0 | 1', + primitive: 'number', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -545,11 +414,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 11, data: { - container: 'union', - nonRedundantType: 'number', - redundantType: '2 | 3', + literal: '2 | 3', + primitive: 'number', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -559,11 +427,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 10, data: { - container: 'union', - nonRedundantType: 'string', - redundantType: '""', + literal: '""', + primitive: 'string', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -576,11 +443,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 18, data: { - container: 'union', - nonRedundantType: 'string', - redundantType: '"b"', + literal: '"b"', + primitive: 'string', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -590,11 +456,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 10, data: { - container: 'union', - nonRedundantType: 'string', - redundantType: '`a${number}c`', + literal: 'template literal type', + primitive: 'string', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -607,11 +472,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 18, data: { - container: 'union', - nonRedundantType: 'string', - redundantType: '`a${number}c`', + literal: 'template literal type', + primitive: 'string', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -621,11 +485,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 10, data: { - container: 'union', - nonRedundantType: 'string', - redundantType: '`${number}`', + literal: 'template literal type', + primitive: 'string', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -635,11 +498,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 10, data: { - container: 'union', - nonRedundantType: 'bigint', - redundantType: '0n', + literal: '0n', + primitive: 'bigint', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -649,11 +511,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 10, data: { - container: 'union', - nonRedundantType: 'bigint', - redundantType: '-1n', + literal: '-1n', + primitive: 'bigint', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -663,11 +524,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 11, data: { - container: 'union', - nonRedundantType: 'bigint', - redundantType: '-1n | 1n', + literal: '-1n | 1n', + primitive: 'bigint', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -680,11 +540,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 22, data: { - container: 'union', - nonRedundantType: 'boolean', - redundantType: 'false', + literal: 'false', + primitive: 'boolean', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -694,11 +553,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 10, data: { - container: 'union', - nonRedundantType: 'boolean', - redundantType: 'false', + literal: 'false', + primitive: 'boolean', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -708,11 +566,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 10, data: { - container: 'union', - nonRedundantType: 'boolean', - redundantType: 'true', + literal: 'true', + primitive: 'boolean', }, - messageId: 'typeOverridden', + messageId: 'literalOverridden', }, ], }, @@ -722,11 +579,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 18, data: { - container: 'intersection', - nonRedundantType: 'false', - redundantType: 'boolean', + literal: 'false', + primitive: 'boolean', }, - messageId: 'typeOverridden', + messageId: 'primitiveOverridden', }, ], }, @@ -739,11 +595,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 22, data: { - container: 'intersection', - nonRedundantType: 'false', - redundantType: 'boolean', + literal: 'false', + primitive: 'boolean', }, - messageId: 'typeOverridden', + messageId: 'primitiveOverridden', }, ], }, @@ -756,11 +611,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 22, data: { - container: 'intersection', - nonRedundantType: 'true', - redundantType: 'boolean', + literal: 'true', + primitive: 'boolean', }, - messageId: 'typeOverridden', + messageId: 'primitiveOverridden', }, ], }, @@ -770,11 +624,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 17, data: { - container: 'intersection', - nonRedundantType: 'true', - redundantType: 'boolean', + literal: 'true', + primitive: 'boolean', }, - messageId: 'typeOverridden', + messageId: 'primitiveOverridden', }, ], }, @@ -891,11 +744,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 10, data: { - container: 'intersection', - nonRedundantType: '0', - redundantType: 'number', + literal: '0', + primitive: 'number', }, - messageId: 'typeOverridden', + messageId: 'primitiveOverridden', }, ], }, @@ -905,11 +757,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 15, data: { - container: 'intersection', - nonRedundantType: '""', - redundantType: 'string', + literal: '""', + primitive: 'string', }, - messageId: 'typeOverridden', + messageId: 'primitiveOverridden', }, ], }, @@ -922,11 +773,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 22, data: { - container: 'intersection', - nonRedundantType: '0n', - redundantType: 'bigint', + literal: '0n', + primitive: 'bigint', }, - messageId: 'typeOverridden', + messageId: 'primitiveOverridden', }, ], }, @@ -936,11 +786,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 15, data: { - container: 'intersection', - nonRedundantType: '0n', - redundantType: 'bigint', + literal: '0n', + primitive: 'bigint', }, - messageId: 'typeOverridden', + messageId: 'primitiveOverridden', }, ], }, @@ -950,11 +799,10 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 16, data: { - container: 'intersection', - nonRedundantType: '-1n', - redundantType: 'bigint', + literal: '-1n', + primitive: 'bigint', }, - messageId: 'typeOverridden', + messageId: 'primitiveOverridden', }, ], }, @@ -965,13 +813,12 @@ ruleTester.run('no-redundant-type-constituents', rule, { `, errors: [ { - column: 22, + column: 18, data: { - container: 'intersection', - nonRedundantType: 'T', - redundantType: 'string', + literal: '"a" | "b"', + primitive: 'string', }, - messageId: 'typeOverridden', + messageId: 'primitiveOverridden', }, ], }, @@ -981,1320 +828,22 @@ ruleTester.run('no-redundant-type-constituents', rule, { type T = 'a' | 'b'; type U = S & T & string & number; `, - errors: [ - { - column: 26, - data: { - container: 'intersection', - nonRedundantType: 'T', - redundantType: 'string', - }, - endColumn: 32, - line: 4, - messageId: 'typeOverridden', - }, - { - column: 35, - data: { - container: 'intersection', - nonRedundantType: 'S', - redundantType: 'number', - }, - endColumn: 41, - line: 4, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = { a: 1 } | any;', - errors: [ - { - column: 21, - data: { - container: 'union', - typeName: 'any', - }, - messageId: 'overrides', - }, - ], - }, - { - code: ` - type B = { a: 1 }; - type T = B | any; - `, - errors: [ - { - column: 22, - data: { - container: 'union', - typeName: 'any', - }, - messageId: 'overrides', - }, - ], - }, - { - code: 'type T = any | { a: 1 };', - errors: [ - { - column: 10, - data: { - container: 'union', - typeName: 'any', - }, - messageId: 'overrides', - }, - ], - }, - { - code: ` - type B = any; - type T = B | { a: 1 }; - `, errors: [ { column: 18, data: { - container: 'union', - typeName: 'any', - }, - messageId: 'overrides', - }, - ], - }, - { - code: 'type T = { a: 1 } | never;', - errors: [ - { - column: 21, - data: { - container: 'union', - typeName: 'never', + literal: '1 | 2', + primitive: 'number', }, - messageId: 'overridden', + messageId: 'primitiveOverridden', }, - ], - }, - { - code: ` - type B = { a: 1 }; - type T = B | never; - `, - errors: [ { column: 22, data: { - container: 'union', - typeName: 'never', - }, - messageId: 'overridden', - }, - ], - }, - { - code: ` - type B = never; - type T = B | { a: 1 }; - `, - errors: [ - { - column: 18, - data: { - container: 'union', - typeName: 'never', - }, - messageId: 'overridden', - }, - ], - }, - { - code: 'type T = never | { a: 1 };', - errors: [ - { - column: 10, - data: { - container: 'union', - typeName: 'never', - }, - messageId: 'overridden', - }, - ], - }, - { - code: 'type T = { a: 1 } | unknown;', - errors: [ - { - column: 21, - data: { - container: 'union', - typeName: 'unknown', - }, - messageId: 'overrides', - }, - ], - }, - { - code: 'type T = unknown | { a: 1 };', - errors: [ - { - column: 10, - data: { - container: 'union', - typeName: 'unknown', - }, - messageId: 'overrides', - }, - ], - }, - { - code: 'type ErrorTypes = NotKnown | { a: 1 };', - errors: [ - { - column: 19, - data: { - container: 'union', - typeName: 'NotKnown', - }, - messageId: 'errorTypeOverrides', - }, - ], - }, - { - code: 'type Foo = { a: 1 | 2 } | ({ a: 1 } & { a: 1 | 3 });', - errors: [ - { - column: 28, - data: { - container: 'union', - nonRedundantType: '{ a: 1 | 2; }', - redundantType: '{ a: 1; } & { a: 1 | 3; }', - }, - endColumn: 51, - messageId: 'typeOverridden', - }, - { - column: 39, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1; }', - redundantType: '{ a: 1 | 3; }', - }, - endColumn: 51, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type Foo = { a: 1 | 2 } | ({ a: 1 } | ({ a: 2 } & { a: 1 | 2 }));', - errors: [ - { - column: 28, - data: { - container: 'union', - nonRedundantType: '{ a: 1 | 2; }', - redundantType: '{ a: 1; } | ({ a: 2; } & { a: 1 | 2; })', - }, - endColumn: 64, - messageId: 'typeOverridden', - }, - { - column: 51, - data: { - container: 'intersection', - nonRedundantType: '{ a: 2; }', - redundantType: '{ a: 1 | 2; }', - }, - endColumn: 63, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type Foo = { a: 1 } | ({ a: 3 } | ({ a: 1 | 2 } & { a: number }));', - errors: [ - { - column: 12, - data: { - container: 'union', - nonRedundantType: '{ a: 1 | 2; } & { a: number; }', - redundantType: '{ a: 1; }', - }, - endColumn: 20, - messageId: 'typeOverridden', - }, - { - column: 51, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1 | 2; }', - redundantType: '{ a: number; }', - }, - endColumn: 64, - messageId: 'typeOverridden', - }, - ], - }, - { - code: ` -type R = { a: 1 | 2 } & { a: number }; -type T = R | { a: 1 }; - `, - errors: [ - { - column: 25, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1 | 2; }', - redundantType: '{ a: number; }', - }, - endColumn: 38, - line: 2, - messageId: 'typeOverridden', - }, - { - column: 14, - data: { - container: 'union', - nonRedundantType: 'R', - redundantType: '{ a: 1; }', - }, - endColumn: 22, - line: 3, - messageId: 'typeOverridden', - }, - ], - }, - { - code: ` -type R = ({ a: 1; b: 2; c: 1 } & { a: 1; b: 2 }) | { a: 2; b: 1 }; -type P = R & { a: number; b: number }; - `, - errors: [ - { - column: 34, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1; b: 2; c: 1; }', - redundantType: '{ a: 1; b: 2; }', - }, - endColumn: 48, - line: 2, - messageId: 'typeOverridden', - }, - { - column: 14, - data: { - container: 'intersection', - nonRedundantType: 'R', - redundantType: '{ a: number; b: number; }', - }, - endColumn: 38, - line: 3, - messageId: 'typeOverridden', - }, - ], - }, - { - code: ` -type R = { a: 1 | 2 } & { a: number }; -type T = R | { a: 1 }; -type U = T | { a: 2 }; - `, - errors: [ - { - column: 25, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1 | 2; }', - redundantType: '{ a: number; }', - }, - endColumn: 38, - line: 2, - messageId: 'typeOverridden', - }, - { - column: 14, - data: { - container: 'union', - nonRedundantType: 'R', - redundantType: '{ a: 1; }', - }, - endColumn: 22, - line: 3, - messageId: 'typeOverridden', - }, - { - column: 14, - data: { - container: 'union', - nonRedundantType: 'T', - redundantType: '{ a: 2; }', - }, - endColumn: 22, - line: 4, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = { a: false } & { a: boolean };', - errors: [ - { - column: 25, - data: { - container: 'intersection', - nonRedundantType: '{ a: false; }', - redundantType: '{ a: boolean; }', - }, - endColumn: 39, - messageId: 'typeOverridden', - }, - ], - }, - { - code: ` -type B = { a: false }; -type T = B & { a: boolean }; - `, - errors: [ - { - column: 14, - data: { - container: 'intersection', - nonRedundantType: 'B', - redundantType: '{ a: boolean; }', - }, - endColumn: 28, - line: 3, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = { a: true } & { a: boolean };', - errors: [ - { - column: 24, - data: { - container: 'intersection', - nonRedundantType: '{ a: true; }', - redundantType: '{ a: boolean; }', - }, - endColumn: 38, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = { a: number } & any;', - errors: [ - { - column: 26, - data: { - container: 'intersection', - typeName: 'any', - }, - messageId: 'overrides', - }, - ], - }, - { - code: 'type T = any & { a: number };', - errors: [ - { - column: 10, - data: { - container: 'intersection', - typeName: 'any', - }, - messageId: 'overrides', - }, - ], - }, - { - code: 'type ErrorTypes = NotKnown & { a: 0 };', - errors: [ - { - column: 19, - data: { - container: 'intersection', - typeName: 'NotKnown', - }, - messageId: 'errorTypeOverrides', - }, - ], - }, - { - code: 'type T = { a: number } & never;', - errors: [ - { - column: 26, - data: { - container: 'intersection', - typeName: 'never', - }, - messageId: 'overrides', - }, - ], - }, - { - code: ` - type B = never; - type T = B & { a: number }; - `, - errors: [ - { - column: 18, - data: { - container: 'intersection', - typeName: 'never', - }, - line: 3, - messageId: 'overrides', - }, - ], - }, - { - code: 'type T = never & { a: number };', - errors: [ - { - column: 10, - data: { - container: 'intersection', - typeName: 'never', - }, - messageId: 'overrides', - }, - ], - }, - { - code: 'type T = { a: number } & unknown;', - errors: [ - { - column: 26, - data: { - container: 'intersection', - typeName: 'unknown', - }, - messageId: 'overridden', - }, - ], - }, - { - code: 'type T = unknown & { a: number };', - errors: [ - { - column: 10, - data: { - container: 'intersection', - typeName: 'unknown', - }, - messageId: 'overridden', - }, - ], - }, - { - code: ` -type T = { a: 1 } | { a: 2 }; -type U = T & { a: number }; - `, - errors: [ - { - column: 14, - data: { - container: 'intersection', - nonRedundantType: 'T', - redundantType: '{ a: number; }', - }, - endColumn: 27, - line: 3, - messageId: 'typeOverridden', - }, - ], - }, - { - code: ` -type S = { a: 1 } | { a: 2 }; -type T = { a: 'a' } | { a: 'b' }; -type U = S & T & { a: string } & { a: number }; - `, - errors: [ - { - column: 18, - data: { - container: 'intersection', - nonRedundantType: 'T', - redundantType: '{ a: string; }', - }, - endColumn: 31, - line: 4, - messageId: 'typeOverridden', - }, - { - column: 34, - data: { - container: 'intersection', - nonRedundantType: 'S', - redundantType: '{ a: number; }', - }, - endColumn: 47, - line: 4, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = { a: 1 | 2 } & { a: number } & { a: 1 };', - errors: [ - { - column: 10, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1; }', - redundantType: '{ a: 1 | 2; }', - }, - endColumn: 22, - messageId: 'typeOverridden', - }, - { - column: 25, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1 | 2; }', - redundantType: '{ a: number; }', - }, - endColumn: 38, - messageId: 'typeOverridden', - }, - { - column: 25, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1; }', - redundantType: '{ a: number; }', - }, - endColumn: 38, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type Foo = ({ a: number } & { b: number }) & { a: 1; b: 1 };', - errors: [ - { - column: 13, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1; b: 1; }', - redundantType: '{ a: number; } & { b: number; }', - }, - endColumn: 42, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type Foo = ({ a: number } & { b: number }) & { a: 1 } & { b: 1 };', - errors: [ - { - column: 13, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1; }', - redundantType: '{ a: number; }', - }, - endColumn: 42, - messageId: 'typeOverridden', - }, - { - column: 13, - data: { - container: 'intersection', - nonRedundantType: '{ b: 1; }', - redundantType: '{ b: number; }', - }, - endColumn: 42, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type Foo = { a: 1; b: 1 } | ({ a: number } & ({ b: 1 } | { d: 1 }));', - errors: [ - { - column: 12, - data: { - container: 'union', - nonRedundantType: '{ a: number; } & ({ b: 1; } | { d: 1; })', - redundantType: '{ a: 1; b: 1; }', - }, - endColumn: 26, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type F = { a: 1 } & ({ a: 1; b: 1 } | { a: 1 });', - errors: [ - { - column: 10, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1; b: 1; } | { a: 1; }', - redundantType: '{ a: 1; }', - }, - endColumn: 18, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type F = ({ a: 1; b: 1 } | { a: 1 }) & { a: 1 };', - errors: [ - { - column: 40, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1; b: 1; } | { a: 1; }', - redundantType: '{ a: 1; }', - }, - endColumn: 48, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type F = { a: 1; b: 1 } & ({ a: 1 } | { b: 1 });', - errors: [ - { - column: 28, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1; b: 1; }', - redundantType: '{ a: 1; } | { b: 1; }', - }, - endColumn: 47, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type F = { a: 1 } & { a: 1; b: 1 };', - errors: [ - { - column: 10, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1; b: 1; }', - redundantType: '{ a: 1; }', - }, - endColumn: 18, - messageId: 'typeOverridden', - }, - ], - }, - { - code: ` -type R = { a: 1; b: 2 } | { a: 2; b: 1 }; -type T = { a: number } | { b: number }; -type U = R & T; - `, - errors: [ - { - column: 14, - data: { - container: 'intersection', - nonRedundantType: 'R', - redundantType: 'T', - }, - endColumn: 15, - line: 4, - messageId: 'typeOverridden', - }, - ], - }, - { - code: ` -type T = { a: 1; b: 1 }; -type U = Omit & Required; -type K = U<'a'>; -type R = K & { a: 1 }; - `, - errors: [ - { - column: 14, - data: { - container: 'intersection', - nonRedundantType: 'K', - redundantType: '{ a: 1; }', - }, - endColumn: 22, - line: 5, - messageId: 'typeOverridden', - }, - ], - }, - { - code: ` -interface T { - a: 1; -} -type U = T | { a: number }; - `, - errors: [ - { - column: 10, - data: { - container: 'union', - nonRedundantType: '{ a: number; }', - redundantType: 'T', - }, - endColumn: 11, - messageId: 'typeOverridden', - }, - ], - }, - { - code: ` -type T = { a: '1'; b: '2' }; -type U = { - [Property in keyof Type]: 0; -}; -type F = U | { a: number; b: number }; - `, - errors: [ - { - column: 10, - data: { - container: 'union', - nonRedundantType: '{ a: number; b: number; }', - redundantType: 'U', - }, - endColumn: 14, - line: 6, - messageId: 'typeOverridden', - }, - ], - }, - { - code: ` -type T = { a: '1'; b: '2' }; -type U = { - [Property in keyof Type]: 0; -}; -type F = U & { a: number; b: number }; - `, - errors: [ - { - column: 17, - data: { - container: 'intersection', - nonRedundantType: 'U', - redundantType: '{ a: number; b: number; }', - }, - endColumn: 41, - line: 6, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = Partial<{ a: 1 }> | { a: 1 };', - errors: [ - { - column: 30, - data: { - container: 'union', - nonRedundantType: 'Partial<{ a: 1; }>', - redundantType: '{ a: 1; }', - }, - endColumn: 38, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = Partial<{ a: 1 }> & { a: 1 };', - errors: [ - { - column: 10, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1; }', - redundantType: 'Partial<{ a: 1; }>', - }, - endColumn: 27, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = { a?: 1 } & { a: 1; b?: 1 };', - errors: [ - { - column: 10, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1; b?: 1 | undefined; }', - redundantType: '{ a?: 1 | undefined; }', - }, - endColumn: 19, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = { a: 1 } & { a: 1; b?: 1 };', - errors: [ - { - column: 10, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1; b?: 1 | undefined; }', - redundantType: '{ a: 1; }', - }, - endColumn: 18, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = { a: { b: 1 } } & { a: { b: 1; c?: 1 } };', - errors: [ - { - column: 10, - data: { - container: 'intersection', - nonRedundantType: '{ a: { b: 1; c?: 1 | undefined; }; }', - redundantType: '{ a: { b: 1; }; }', - }, - endColumn: 25, - messageId: 'typeOverridden', - }, - ], - }, - { - code: ` -interface A { - a: 1; -} -interface B extends A { - b: 1; -} -type C = A & B; - `, - errors: [ - { - column: 10, - data: { - container: 'intersection', - nonRedundantType: 'B', - redundantType: 'A', - }, - endColumn: 11, - line: 8, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = { a: 1 } | { a: number } | { a: number };', - errors: [ - { - column: 10, - data: { - container: 'union', - nonRedundantType: '{ a: number; }', - redundantType: '{ a: 1; }', - }, - endColumn: 18, - messageId: 'typeOverridden', - }, - { - column: 10, - data: { - container: 'union', - nonRedundantType: '{ a: number; }', - redundantType: '{ a: 1; }', - }, - endColumn: 18, - messageId: 'typeOverridden', - }, - ], - }, - { - code: "declare function fn(): (never | 'foo') & string;", - errors: [ - { - column: 25, - data: { - container: 'union', - typeName: 'never', - }, - endColumn: 30, - messageId: 'overridden', - }, - { - column: 42, - data: { - container: 'intersection', - nonRedundantType: '"foo"', - redundantType: 'string', - }, - endColumn: 48, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = { a: 1 } | ({ a: 1 } & ({ a: 1 } | { b: 1 }));', - errors: [ - { - column: 10, - data: { - container: 'union', - nonRedundantType: '{ a: 1; } & ({ a: 1; } | { b: 1; })', - redundantType: '{ a: 1; }', - }, - endColumn: 18, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = { a: 1; b: 1 } | ({ a: 1 } & ({ b: number } | { b: number }));', - errors: [ - { - column: 10, - data: { - container: 'union', - nonRedundantType: '{ a: 1; } & ({ b: number; } | { b: number; })', - redundantType: '{ a: 1; b: 1; }', - }, - endColumn: 24, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = ({ a: 1 } & ({ a: 1 } | { b: 1 })) | { a: 1 };', - errors: [ - { - column: 47, - data: { - container: 'union', - nonRedundantType: '{ a: 1; } & ({ a: 1; } | { b: 1; })', - redundantType: '{ a: 1; }', - }, - endColumn: 55, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = { a: 1 | 3 } | { a: 1 | 3 | 5 };', - errors: [ - { - column: 10, - data: { - container: 'union', - nonRedundantType: '{ a: 1 | 3 | 5; }', - redundantType: '{ a: 1 | 3; }', - }, - endColumn: 22, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = { a: 1 | 3 | { b: 1 } } | { a: 1 | 3 | 5 | { b: 1 | 2 } };', - errors: [ - { - column: 10, - data: { - container: 'union', - nonRedundantType: '{ a: 1 | 3 | 5 | { b: 1 | 2; }; }', - redundantType: '{ a: 1 | 3 | { b: 1; }; }', - }, - endColumn: 33, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = { a: 1 | 3 } & { a: 1 | 3 | 5 };', - errors: [ - { - column: 25, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1 | 3; }', - redundantType: '{ a: 1 | 3 | 5; }', - }, - endColumn: 41, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = { a: 1 | { a?: 1; b: 1 } } & { a: 1 | { b: 1 } };', - errors: [ - { - column: 39, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1 | { a?: 1 | undefined; b: 1; }; }', - redundantType: '{ a: 1 | { b: 1; }; }', - }, - endColumn: 58, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = { a: 1 | 3 | { b: 1 } } & { a: 1 | { b: 1 } };', - errors: [ - { - column: 10, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1 | { b: 1; }; }', - redundantType: '{ a: 1 | 3 | { b: 1; }; }', - }, - endColumn: 33, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = { a: 1 | 3 | { b: 1 } } & { a: 1 | { b: 1; c: 1 } };', - errors: [ - { - column: 10, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1 | { b: 1; c: 1; }; }', - redundantType: '{ a: 1 | 3 | { b: 1; }; }', - }, - endColumn: 33, - messageId: 'typeOverridden', - }, - ], - }, - { - code: ` - type R = { a: 1 } | { a: 2 }; - type T = { a: 1 | 2 } | { a: 3 }; - type U = R | T; - `, - errors: [ - { - column: 18, - data: { - container: 'union', - nonRedundantType: 'T', - redundantType: 'R', - }, - endColumn: 19, - line: 4, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = [] | number[];', - errors: [ - { - column: 10, - data: { - container: 'union', - nonRedundantType: 'number[]', - redundantType: '[]', - }, - endColumn: 12, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = Array | [1, 2, 3, 4];', - errors: [ - { - column: 26, - data: { - container: 'union', - nonRedundantType: 'number[]', - redundantType: '[1, 2, 3, 4]', - }, - endColumn: 38, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = Array | Array<1>;', - errors: [ - { - column: 26, - data: { - container: 'union', - nonRedundantType: 'number[]', - redundantType: '1[]', - }, - endColumn: 34, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = [{ a: number }] | [{ a: 1 }];', - errors: [ - { - column: 28, - data: { - container: 'union', - nonRedundantType: '[{ a: number; }]', - redundantType: '[{ a: 1; }]', - }, - endColumn: 38, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = Array<{ a: number }> | Array<{ a: 1 }>;', - errors: [ - { - column: 33, - data: { - container: 'union', - nonRedundantType: '{ a: number; }[]', - redundantType: '{ a: 1; }[]', - }, - endColumn: 48, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = [] & number[];', - errors: [ - { - column: 15, - data: { - container: 'intersection', - nonRedundantType: '[]', - redundantType: 'number[]', - }, - endColumn: 23, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = [1, 2, 3, 4] & Array;', - errors: [ - { - column: 25, - data: { - container: 'intersection', - nonRedundantType: '[1, 2, 3, 4]', - redundantType: 'number[]', - }, - endColumn: 38, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = Array & Array<1>;', - errors: [ - { - column: 10, - data: { - container: 'intersection', - nonRedundantType: '1[]', - redundantType: 'number[]', - }, - endColumn: 23, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = [{ a: number }] & [{ a: 1 }];', - errors: [ - { - column: 10, - data: { - container: 'intersection', - nonRedundantType: '[{ a: 1; }]', - redundantType: '[{ a: number; }]', - }, - endColumn: 25, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = Array<{ a: number }> & Array<{ a: 1 }>;', - errors: [ - { - column: 10, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1; }[]', - redundantType: '{ a: number; }[]', - }, - endColumn: 30, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = Array<{ a: number }> & Array<{ a: 1; b: 1 }>;', - errors: [ - { - column: 10, - data: { - container: 'intersection', - nonRedundantType: '{ a: 1; b: 1; }[]', - redundantType: '{ a: number; }[]', - }, - endColumn: 30, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = [{ a: 1 }] & [{ a: 1; b?: 1 }];', - errors: [ - { - column: 10, - data: { - container: 'intersection', - nonRedundantType: '[{ a: 1; b?: 1 | undefined; }]', - redundantType: '[{ a: 1; }]', - }, - endColumn: 20, - messageId: 'typeOverridden', - }, - ], - }, - { - code: 'type T = [{ a: number }] & [{ a: 1; b: 1 }];', - errors: [ - { - column: 10, - data: { - container: 'intersection', - nonRedundantType: '[{ a: 1; b: 1; }]', - redundantType: '[{ a: number; }]', + literal: '"a" | "b"', + primitive: 'string', }, - endColumn: 25, - messageId: 'typeOverridden', + messageId: 'primitiveOverridden', }, ], }, diff --git a/packages/scope-manager/tests/test-utils/serializers/TSESTreeNode.ts b/packages/scope-manager/tests/test-utils/serializers/TSESTreeNode.ts index cad4cb206d25..733deaa0257d 100644 --- a/packages/scope-manager/tests/test-utils/serializers/TSESTreeNode.ts +++ b/packages/scope-manager/tests/test-utils/serializers/TSESTreeNode.ts @@ -17,10 +17,7 @@ const EXCLUDED_KEYS = new Set([ const generator = createIdGenerator(); type Node = { type: AST_NODE_TYPES } & Record; -type Identifier = { name: string; type: AST_NODE_TYPES.Identifier } & Record< - string, - unknown ->; +type Identifier = { name: string; type: AST_NODE_TYPES.Identifier } & Node; const SEEN_NODES = new Map(); export const serializer: NewPlugin = { diff --git a/packages/typescript-estree/src/parser-options.ts b/packages/typescript-estree/src/parser-options.ts index f643ccf19bcf..a1841a828d48 100644 --- a/packages/typescript-estree/src/parser-options.ts +++ b/packages/typescript-estree/src/parser-options.ts @@ -7,7 +7,7 @@ import type { } from '@typescript-eslint/types'; import type * as ts from 'typescript'; -import type { TSESTree, TSESTreeToTSNode, TSToken } from './ts-estree'; +import type { TSESTree, TSESTreeToTSNode, TSNode, TSToken } from './ts-estree'; ////////////////////////////////////////////////////////// // MAKE SURE THIS IS KEPT IN SYNC WITH THE WEBSITE DOCS // @@ -242,7 +242,7 @@ export interface ParserServicesBase { } export interface ParserServicesNodeMaps { esTreeNodeToTSNodeMap: ParserWeakMapESTreeToTSNode; - tsNodeToESTreeNodeMap: ParserWeakMap; + tsNodeToESTreeNodeMap: ParserWeakMap; } export interface ParserServicesWithTypeInformation extends ParserServicesNodeMaps, diff --git a/packages/typescript-estree/src/semantic-or-syntactic-errors.ts b/packages/typescript-estree/src/semantic-or-syntactic-errors.ts index 077382409f3a..a88a3615d9f8 100644 --- a/packages/typescript-estree/src/semantic-or-syntactic-errors.ts +++ b/packages/typescript-estree/src/semantic-or-syntactic-errors.ts @@ -1,4 +1,9 @@ -import type { Diagnostic, Program, SourceFile } from 'typescript'; +import type { + Diagnostic, + DiagnosticWithLocation, + Program, + SourceFile, +} from 'typescript'; import { flattenDiagnosticMessageText, sys } from 'typescript'; @@ -54,8 +59,8 @@ export function getFirstSemanticOrSyntacticError( } function allowlistSupportedDiagnostics( - diagnostics: readonly Diagnostic[], -): readonly Diagnostic[] { + diagnostics: readonly (Diagnostic | DiagnosticWithLocation)[], +): readonly (Diagnostic | DiagnosticWithLocation)[] { return diagnostics.filter(diagnostic => { switch (diagnostic.code) { case 1013: // "A rest parameter or binding pattern may not have a trailing comma." diff --git a/packages/utils/src/ts-eslint/Config.ts b/packages/utils/src/ts-eslint/Config.ts index a4cf356e2dbc..95ab05d9f2f2 100644 --- a/packages/utils/src/ts-eslint/Config.ts +++ b/packages/utils/src/ts-eslint/Config.ts @@ -147,7 +147,7 @@ export namespace FlatConfig { export type Settings = SharedConfigurationSettings; export type Severity = SharedConfig.Severity; export type SeverityString = SharedConfig.SeverityString; - export type SourceType = ParserOptionsTypes.SourceType; + export type SourceType = 'commonjs' | ParserOptionsTypes.SourceType; export interface SharedConfigs { [key: string]: Config | ConfigArray; @@ -219,7 +219,7 @@ export namespace FlatConfig { * Set to `"latest"` for the most recent supported version. * @default "latest" */ - ecmaVersion?: EcmaVersion; + ecmaVersion?: EcmaVersion | undefined; /** * An object specifying additional objects that should be added to the global scope during linting. */ diff --git a/packages/website/src/components/ast/DataRenderer.tsx b/packages/website/src/components/ast/DataRenderer.tsx index e684e4f312df..4619fd579bc1 100644 --- a/packages/website/src/components/ast/DataRenderer.tsx +++ b/packages/website/src/components/ast/DataRenderer.tsx @@ -30,7 +30,8 @@ export interface JsonRenderProps { readonly value: T; } -export interface ExpandableRenderProps extends JsonRenderProps { +export interface ExpandableRenderProps + extends JsonRenderProps { readonly closeBracket: string; readonly data: [string, unknown][]; readonly openBracket: string; diff --git a/packages/website/src/components/hooks/useHashState.ts b/packages/website/src/components/hooks/useHashState.ts index fac9734b0936..18fb35d3ce00 100644 --- a/packages/website/src/components/hooks/useHashState.ts +++ b/packages/website/src/components/hooks/useHashState.ts @@ -75,7 +75,7 @@ const parseStateFromUrl = ( ); } - let esQuery: ConfigModel['esQuery']; + let esQuery: ConfigModel['esQuery'] | undefined; if (searchParams.has('esQuery')) { esQuery = JSON.parse( readQueryParam(searchParams.get('esQuery'), ''), From 8fe34456f75c1d1e8a4dc518306d5ab93422efec Mon Sep 17 00:00:00 2001 From: "typescript-eslint[bot]" Date: Tue, 2 Dec 2025 08:44:48 +0000 Subject: [PATCH 14/14] chore(release): publish 8.48.1 --- CHANGELOG.md | 17 ++++ packages/ast-spec/CHANGELOG.md | 6 ++ packages/ast-spec/package.json | 2 +- packages/eslint-plugin/CHANGELOG.md | 17 ++++ packages/eslint-plugin/package.json | 16 +-- packages/parser/CHANGELOG.md | 6 ++ packages/parser/package.json | 10 +- packages/project-service/CHANGELOG.md | 6 ++ packages/project-service/package.json | 6 +- .../CHANGELOG.md | 6 ++ .../package.json | 6 +- packages/rule-tester/CHANGELOG.md | 6 ++ packages/rule-tester/package.json | 8 +- packages/scope-manager/CHANGELOG.md | 6 ++ packages/scope-manager/package.json | 8 +- packages/tsconfig-utils/CHANGELOG.md | 6 ++ packages/tsconfig-utils/package.json | 2 +- packages/type-utils/CHANGELOG.md | 6 ++ packages/type-utils/package.json | 10 +- packages/types/CHANGELOG.md | 6 ++ packages/types/package.json | 2 +- packages/typescript-eslint/CHANGELOG.md | 6 ++ packages/typescript-eslint/package.json | 10 +- packages/typescript-estree/CHANGELOG.md | 6 ++ packages/typescript-estree/package.json | 10 +- packages/utils/CHANGELOG.md | 6 ++ packages/utils/package.json | 8 +- packages/visitor-keys/CHANGELOG.md | 6 ++ packages/visitor-keys/package.json | 4 +- yarn.lock | 98 +++++++++---------- 30 files changed, 212 insertions(+), 100 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44a6a7513931..6a8cbc1a3225 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +## 8.48.1 (2025-12-02) + +### 🩹 Fixes + +- **eslint-plugin:** [consistent-type-exports] check value flag before resolving alias ([#11769](https://github.com/typescript-eslint/typescript-eslint/pull/11769)) +- **eslint-plugin:** honor ignored base types on generic classes ([#11767](https://github.com/typescript-eslint/typescript-eslint/pull/11767)) +- **eslint-plugin:** [restrict-template-expressions] check base types in allow list ([#11764](https://github.com/typescript-eslint/typescript-eslint/pull/11764), [#11759](https://github.com/typescript-eslint/typescript-eslint/issues/11759)) + +### ❤️ Thank You + +- Josh Goldberg +- OleksandraKordonets +- SangheeSon @Higangssh +- tao + +You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. + ## 8.48.0 (2025-11-24) ### 🚀 Features diff --git a/packages/ast-spec/CHANGELOG.md b/packages/ast-spec/CHANGELOG.md index c82ce9b0286b..0a180abc6a07 100644 --- a/packages/ast-spec/CHANGELOG.md +++ b/packages/ast-spec/CHANGELOG.md @@ -1,3 +1,9 @@ +## 8.48.1 (2025-12-02) + +This was a version bump only for ast-spec to align it with other projects, there were no code changes. + +You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. + ## 8.48.0 (2025-11-24) ### 🩹 Fixes diff --git a/packages/ast-spec/package.json b/packages/ast-spec/package.json index f7f3f4773522..9b9a17e0bd61 100644 --- a/packages/ast-spec/package.json +++ b/packages/ast-spec/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/ast-spec", - "version": "8.48.0", + "version": "8.48.1", "description": "Complete specification for the TypeScript-ESTree AST", "private": true, "keywords": [ diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index 4dea8bb550dc..eb952cc00512 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -1,3 +1,20 @@ +## 8.48.1 (2025-12-02) + +### 🩹 Fixes + +- **eslint-plugin:** [restrict-template-expressions] check base types in allow list ([#11764](https://github.com/typescript-eslint/typescript-eslint/pull/11764), [#11759](https://github.com/typescript-eslint/typescript-eslint/issues/11759)) +- **eslint-plugin:** honor ignored base types on generic classes ([#11767](https://github.com/typescript-eslint/typescript-eslint/pull/11767)) +- **eslint-plugin:** [consistent-type-exports] check value flag before resolving alias ([#11769](https://github.com/typescript-eslint/typescript-eslint/pull/11769)) + +### ❤️ Thank You + +- Josh Goldberg +- OleksandraKordonets +- SangheeSon @Higangssh +- tao + +You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. + ## 8.48.0 (2025-11-24) ### 🚀 Features diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index c452887ca310..3dd5a00889db 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin", - "version": "8.48.0", + "version": "8.48.1", "description": "TypeScript plugin for ESLint", "files": [ "dist", @@ -59,10 +59,10 @@ }, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.48.0", - "@typescript-eslint/type-utils": "8.48.0", - "@typescript-eslint/utils": "8.48.0", - "@typescript-eslint/visitor-keys": "8.48.0", + "@typescript-eslint/scope-manager": "8.48.1", + "@typescript-eslint/type-utils": "8.48.1", + "@typescript-eslint/utils": "8.48.1", + "@typescript-eslint/visitor-keys": "8.48.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -71,8 +71,8 @@ "devDependencies": { "@types/mdast": "^4.0.3", "@types/natural-compare": "*", - "@typescript-eslint/rule-schema-to-typescript-types": "8.48.0", - "@typescript-eslint/rule-tester": "8.48.0", + "@typescript-eslint/rule-schema-to-typescript-types": "8.48.1", + "@typescript-eslint/rule-tester": "8.48.1", "@vitest/coverage-v8": "^3.1.3", "ajv": "^6.12.6", "cross-fetch": "*", @@ -92,7 +92,7 @@ "vitest": "^3.1.3" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.48.0", + "@typescript-eslint/parser": "^8.48.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" }, diff --git a/packages/parser/CHANGELOG.md b/packages/parser/CHANGELOG.md index 9d50518c76c1..faae9f4a8acc 100644 --- a/packages/parser/CHANGELOG.md +++ b/packages/parser/CHANGELOG.md @@ -1,3 +1,9 @@ +## 8.48.1 (2025-12-02) + +This was a version bump only for parser to align it with other projects, there were no code changes. + +You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. + ## 8.48.0 (2025-11-24) This was a version bump only for parser to align it with other projects, there were no code changes. diff --git a/packages/parser/package.json b/packages/parser/package.json index d17ee0e04382..bda118258536 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/parser", - "version": "8.48.0", + "version": "8.48.1", "description": "An ESLint custom parser which leverages TypeScript ESTree", "files": [ "dist", @@ -51,10 +51,10 @@ "typescript": ">=4.8.4 <6.0.0" }, "dependencies": { - "@typescript-eslint/scope-manager": "8.48.0", - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/typescript-estree": "8.48.0", - "@typescript-eslint/visitor-keys": "8.48.0", + "@typescript-eslint/scope-manager": "8.48.1", + "@typescript-eslint/types": "8.48.1", + "@typescript-eslint/typescript-estree": "8.48.1", + "@typescript-eslint/visitor-keys": "8.48.1", "debug": "^4.3.4" }, "devDependencies": { diff --git a/packages/project-service/CHANGELOG.md b/packages/project-service/CHANGELOG.md index e15ae53bb3ba..c18c486ce62e 100644 --- a/packages/project-service/CHANGELOG.md +++ b/packages/project-service/CHANGELOG.md @@ -1,3 +1,9 @@ +## 8.48.1 (2025-12-02) + +This was a version bump only for project-service to align it with other projects, there were no code changes. + +You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. + ## 8.48.0 (2025-11-24) This was a version bump only for project-service to align it with other projects, there were no code changes. diff --git a/packages/project-service/package.json b/packages/project-service/package.json index c4893bfb50ae..706963969bb2 100644 --- a/packages/project-service/package.json +++ b/packages/project-service/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/project-service", - "version": "8.48.0", + "version": "8.48.1", "description": "Standalone TypeScript project service wrapper for linting.", "files": [ "dist", @@ -49,8 +49,8 @@ "typescript": ">=4.8.4 <6.0.0" }, "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.48.0", - "@typescript-eslint/types": "^8.48.0", + "@typescript-eslint/tsconfig-utils": "^8.48.1", + "@typescript-eslint/types": "^8.48.1", "debug": "^4.3.4" }, "devDependencies": { diff --git a/packages/rule-schema-to-typescript-types/CHANGELOG.md b/packages/rule-schema-to-typescript-types/CHANGELOG.md index 1f13e1293745..5e7a0c6d0e0d 100644 --- a/packages/rule-schema-to-typescript-types/CHANGELOG.md +++ b/packages/rule-schema-to-typescript-types/CHANGELOG.md @@ -1,3 +1,9 @@ +## 8.48.1 (2025-12-02) + +This was a version bump only for rule-schema-to-typescript-types to align it with other projects, there were no code changes. + +You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. + ## 8.48.0 (2025-11-24) This was a version bump only for rule-schema-to-typescript-types to align it with other projects, there were no code changes. diff --git a/packages/rule-schema-to-typescript-types/package.json b/packages/rule-schema-to-typescript-types/package.json index f8983bc4acd6..41dd438273d8 100644 --- a/packages/rule-schema-to-typescript-types/package.json +++ b/packages/rule-schema-to-typescript-types/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/rule-schema-to-typescript-types", - "version": "8.48.0", + "version": "8.48.1", "description": "Converts ESLint rule schemas to equivalent TypeScript type strings.", "type": "module", "exports": { @@ -32,8 +32,8 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/type-utils": "8.48.0", - "@typescript-eslint/utils": "8.48.0", + "@typescript-eslint/type-utils": "8.48.1", + "@typescript-eslint/utils": "8.48.1", "natural-compare": "^1.4.0" }, "devDependencies": { diff --git a/packages/rule-tester/CHANGELOG.md b/packages/rule-tester/CHANGELOG.md index 0c170ccef9ce..acb353dde40a 100644 --- a/packages/rule-tester/CHANGELOG.md +++ b/packages/rule-tester/CHANGELOG.md @@ -1,3 +1,9 @@ +## 8.48.1 (2025-12-02) + +This was a version bump only for rule-tester to align it with other projects, there were no code changes. + +You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. + ## 8.48.0 (2025-11-24) ### 🚀 Features diff --git a/packages/rule-tester/package.json b/packages/rule-tester/package.json index aa71d1a8079f..6217601f3233 100644 --- a/packages/rule-tester/package.json +++ b/packages/rule-tester/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/rule-tester", - "version": "8.48.0", + "version": "8.48.1", "description": "Tooling to test ESLint rules", "files": [ "dist", @@ -44,9 +44,9 @@ }, "//": "NOTE - AJV is out-of-date, but it's intentionally synced with ESLint - https://github.com/eslint/eslint/blob/ad9dd6a933fd098a0d99c6a9aa059850535c23ee/package.json#L70", "dependencies": { - "@typescript-eslint/parser": "8.48.0", - "@typescript-eslint/typescript-estree": "8.48.0", - "@typescript-eslint/utils": "8.48.0", + "@typescript-eslint/parser": "8.48.1", + "@typescript-eslint/typescript-estree": "8.48.1", + "@typescript-eslint/utils": "8.48.1", "ajv": "^6.12.6", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "4.6.2", diff --git a/packages/scope-manager/CHANGELOG.md b/packages/scope-manager/CHANGELOG.md index 0a5b2c19ff9d..8ebeae8b3435 100644 --- a/packages/scope-manager/CHANGELOG.md +++ b/packages/scope-manager/CHANGELOG.md @@ -1,3 +1,9 @@ +## 8.48.1 (2025-12-02) + +This was a version bump only for scope-manager to align it with other projects, there were no code changes. + +You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. + ## 8.48.0 (2025-11-24) ### 🚀 Features diff --git a/packages/scope-manager/package.json b/packages/scope-manager/package.json index 770c3ca3d26e..a7c6e3b72905 100644 --- a/packages/scope-manager/package.json +++ b/packages/scope-manager/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/scope-manager", - "version": "8.48.0", + "version": "8.48.1", "description": "TypeScript scope analyser for ESLint", "files": [ "dist", @@ -47,11 +47,11 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/visitor-keys": "8.48.0" + "@typescript-eslint/types": "8.48.1", + "@typescript-eslint/visitor-keys": "8.48.1" }, "devDependencies": { - "@typescript-eslint/typescript-estree": "8.48.0", + "@typescript-eslint/typescript-estree": "8.48.1", "@vitest/coverage-v8": "^3.1.3", "@vitest/pretty-format": "^3.1.3", "eslint": "*", diff --git a/packages/tsconfig-utils/CHANGELOG.md b/packages/tsconfig-utils/CHANGELOG.md index a53cf9e3a787..4ea4097ab534 100644 --- a/packages/tsconfig-utils/CHANGELOG.md +++ b/packages/tsconfig-utils/CHANGELOG.md @@ -1,3 +1,9 @@ +## 8.48.1 (2025-12-02) + +This was a version bump only for tsconfig-utils to align it with other projects, there were no code changes. + +You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. + ## 8.48.0 (2025-11-24) This was a version bump only for tsconfig-utils to align it with other projects, there were no code changes. diff --git a/packages/tsconfig-utils/package.json b/packages/tsconfig-utils/package.json index 35b4112f3996..7c85ab78e125 100644 --- a/packages/tsconfig-utils/package.json +++ b/packages/tsconfig-utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/tsconfig-utils", - "version": "8.48.0", + "version": "8.48.1", "description": "Utilities for collecting TSConfigs for linting scenarios.", "files": [ "dist", diff --git a/packages/type-utils/CHANGELOG.md b/packages/type-utils/CHANGELOG.md index 5366d94fdd5e..8b9006d3f9d8 100644 --- a/packages/type-utils/CHANGELOG.md +++ b/packages/type-utils/CHANGELOG.md @@ -1,3 +1,9 @@ +## 8.48.1 (2025-12-02) + +This was a version bump only for type-utils to align it with other projects, there were no code changes. + +You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. + ## 8.48.0 (2025-11-24) This was a version bump only for type-utils to align it with other projects, there were no code changes. diff --git a/packages/type-utils/package.json b/packages/type-utils/package.json index 9a637841326d..bd6d48af041e 100644 --- a/packages/type-utils/package.json +++ b/packages/type-utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/type-utils", - "version": "8.48.0", + "version": "8.48.1", "description": "Type utilities for working with TypeScript + ESLint together", "files": [ "dist", @@ -44,9 +44,9 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/typescript-estree": "8.48.0", - "@typescript-eslint/utils": "8.48.0", + "@typescript-eslint/types": "8.48.1", + "@typescript-eslint/typescript-estree": "8.48.1", + "@typescript-eslint/utils": "8.48.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -55,7 +55,7 @@ "typescript": ">=4.8.4 <6.0.0" }, "devDependencies": { - "@typescript-eslint/parser": "8.48.0", + "@typescript-eslint/parser": "8.48.1", "@vitest/coverage-v8": "^3.1.3", "ajv": "^6.12.6", "eslint": "*", diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index f62cf2bf1348..00b87545bae8 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -1,3 +1,9 @@ +## 8.48.1 (2025-12-02) + +This was a version bump only for types to align it with other projects, there were no code changes. + +You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. + ## 8.48.0 (2025-11-24) This was a version bump only for types to align it with other projects, there were no code changes. diff --git a/packages/types/package.json b/packages/types/package.json index 6c2fe5c6ff09..7ec61f1974e1 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/types", - "version": "8.48.0", + "version": "8.48.1", "description": "Types for the TypeScript-ESTree AST spec", "files": [ "dist", diff --git a/packages/typescript-eslint/CHANGELOG.md b/packages/typescript-eslint/CHANGELOG.md index 06dfa57847c5..5e38d0cafe67 100644 --- a/packages/typescript-eslint/CHANGELOG.md +++ b/packages/typescript-eslint/CHANGELOG.md @@ -1,3 +1,9 @@ +## 8.48.1 (2025-12-02) + +This was a version bump only for typescript-eslint to align it with other projects, there were no code changes. + +You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. + ## 8.48.0 (2025-11-24) This was a version bump only for typescript-eslint to align it with other projects, there were no code changes. diff --git a/packages/typescript-eslint/package.json b/packages/typescript-eslint/package.json index db25dcd8ce12..b32b4ed2f206 100644 --- a/packages/typescript-eslint/package.json +++ b/packages/typescript-eslint/package.json @@ -1,6 +1,6 @@ { "name": "typescript-eslint", - "version": "8.48.0", + "version": "8.48.1", "description": "Tooling which enables you to use TypeScript with ESLint", "files": [ "dist", @@ -50,10 +50,10 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/eslint-plugin": "8.48.0", - "@typescript-eslint/parser": "8.48.0", - "@typescript-eslint/typescript-estree": "8.48.0", - "@typescript-eslint/utils": "8.48.0" + "@typescript-eslint/eslint-plugin": "8.48.1", + "@typescript-eslint/parser": "8.48.1", + "@typescript-eslint/typescript-estree": "8.48.1", + "@typescript-eslint/utils": "8.48.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", diff --git a/packages/typescript-estree/CHANGELOG.md b/packages/typescript-estree/CHANGELOG.md index 52542a23c60d..fde74b3215e8 100644 --- a/packages/typescript-estree/CHANGELOG.md +++ b/packages/typescript-estree/CHANGELOG.md @@ -1,3 +1,9 @@ +## 8.48.1 (2025-12-02) + +This was a version bump only for typescript-estree to align it with other projects, there were no code changes. + +You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. + ## 8.48.0 (2025-11-24) ### 🚀 Features diff --git a/packages/typescript-estree/package.json b/packages/typescript-estree/package.json index db887a19bea6..ca03700bcab1 100644 --- a/packages/typescript-estree/package.json +++ b/packages/typescript-estree/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/typescript-estree", - "version": "8.48.0", + "version": "8.48.1", "description": "A parser that converts TypeScript source code into an ESTree compatible form", "files": [ "dist", @@ -52,10 +52,10 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/project-service": "8.48.0", - "@typescript-eslint/tsconfig-utils": "8.48.0", - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/visitor-keys": "8.48.0", + "@typescript-eslint/project-service": "8.48.1", + "@typescript-eslint/tsconfig-utils": "8.48.1", + "@typescript-eslint/types": "8.48.1", + "@typescript-eslint/visitor-keys": "8.48.1", "debug": "^4.3.4", "minimatch": "^9.0.4", "semver": "^7.6.0", diff --git a/packages/utils/CHANGELOG.md b/packages/utils/CHANGELOG.md index 3f48c888c19a..716e8fcf6aac 100644 --- a/packages/utils/CHANGELOG.md +++ b/packages/utils/CHANGELOG.md @@ -1,3 +1,9 @@ +## 8.48.1 (2025-12-02) + +This was a version bump only for utils to align it with other projects, there were no code changes. + +You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. + ## 8.48.0 (2025-11-24) ### 🚀 Features diff --git a/packages/utils/package.json b/packages/utils/package.json index 54907514f126..bfae9aedcd57 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/utils", - "version": "8.48.0", + "version": "8.48.1", "description": "Utilities for working with TypeScript + ESLint together", "files": [ "dist", @@ -62,9 +62,9 @@ }, "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.48.0", - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/typescript-estree": "8.48.0" + "@typescript-eslint/scope-manager": "8.48.1", + "@typescript-eslint/types": "8.48.1", + "@typescript-eslint/typescript-estree": "8.48.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", diff --git a/packages/visitor-keys/CHANGELOG.md b/packages/visitor-keys/CHANGELOG.md index ab8735eaa0a3..05e2a32d84e7 100644 --- a/packages/visitor-keys/CHANGELOG.md +++ b/packages/visitor-keys/CHANGELOG.md @@ -1,3 +1,9 @@ +## 8.48.1 (2025-12-02) + +This was a version bump only for visitor-keys to align it with other projects, there were no code changes. + +You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. + ## 8.48.0 (2025-11-24) This was a version bump only for visitor-keys to align it with other projects, there were no code changes. diff --git a/packages/visitor-keys/package.json b/packages/visitor-keys/package.json index 06564f9dd090..68f8a51a406f 100644 --- a/packages/visitor-keys/package.json +++ b/packages/visitor-keys/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/visitor-keys", - "version": "8.48.0", + "version": "8.48.1", "description": "Visitor keys used to help traverse the TypeScript-ESTree AST", "files": [ "dist", @@ -45,7 +45,7 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/types": "8.48.0", + "@typescript-eslint/types": "8.48.1", "eslint-visitor-keys": "^4.2.1" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 101e28c00caf..71d461e97ec8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6143,19 +6143,19 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/eslint-plugin@8.48.0, @typescript-eslint/eslint-plugin@workspace:*, @typescript-eslint/eslint-plugin@workspace:^, @typescript-eslint/eslint-plugin@workspace:packages/eslint-plugin": +"@typescript-eslint/eslint-plugin@8.48.1, @typescript-eslint/eslint-plugin@workspace:*, @typescript-eslint/eslint-plugin@workspace:^, @typescript-eslint/eslint-plugin@workspace:packages/eslint-plugin": version: 0.0.0-use.local resolution: "@typescript-eslint/eslint-plugin@workspace:packages/eslint-plugin" dependencies: "@eslint-community/regexpp": ^4.10.0 "@types/mdast": ^4.0.3 "@types/natural-compare": "*" - "@typescript-eslint/rule-schema-to-typescript-types": 8.48.0 - "@typescript-eslint/rule-tester": 8.48.0 - "@typescript-eslint/scope-manager": 8.48.0 - "@typescript-eslint/type-utils": 8.48.0 - "@typescript-eslint/utils": 8.48.0 - "@typescript-eslint/visitor-keys": 8.48.0 + "@typescript-eslint/rule-schema-to-typescript-types": 8.48.1 + "@typescript-eslint/rule-tester": 8.48.1 + "@typescript-eslint/scope-manager": 8.48.1 + "@typescript-eslint/type-utils": 8.48.1 + "@typescript-eslint/utils": 8.48.1 + "@typescript-eslint/visitor-keys": 8.48.1 "@vitest/coverage-v8": ^3.1.3 ajv: ^6.12.6 cross-fetch: "*" @@ -6178,7 +6178,7 @@ __metadata: unist-util-visit: ^5.0.0 vitest: ^3.1.3 peerDependencies: - "@typescript-eslint/parser": ^8.48.0 + "@typescript-eslint/parser": ^8.48.1 eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <6.0.0" languageName: unknown @@ -6194,14 +6194,14 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/parser@8.48.0, @typescript-eslint/parser@workspace:*, @typescript-eslint/parser@workspace:^, @typescript-eslint/parser@workspace:packages/parser": +"@typescript-eslint/parser@8.48.1, @typescript-eslint/parser@workspace:*, @typescript-eslint/parser@workspace:^, @typescript-eslint/parser@workspace:packages/parser": version: 0.0.0-use.local resolution: "@typescript-eslint/parser@workspace:packages/parser" dependencies: - "@typescript-eslint/scope-manager": 8.48.0 - "@typescript-eslint/types": 8.48.0 - "@typescript-eslint/typescript-estree": 8.48.0 - "@typescript-eslint/visitor-keys": 8.48.0 + "@typescript-eslint/scope-manager": 8.48.1 + "@typescript-eslint/types": 8.48.1 + "@typescript-eslint/typescript-estree": 8.48.1 + "@typescript-eslint/visitor-keys": 8.48.1 "@vitest/coverage-v8": ^3.1.3 debug: ^4.3.4 eslint: "*" @@ -6215,12 +6215,12 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/project-service@8.48.0, @typescript-eslint/project-service@workspace:packages/project-service": +"@typescript-eslint/project-service@8.48.1, @typescript-eslint/project-service@workspace:packages/project-service": version: 0.0.0-use.local resolution: "@typescript-eslint/project-service@workspace:packages/project-service" dependencies: - "@typescript-eslint/tsconfig-utils": ^8.48.0 - "@typescript-eslint/types": ^8.48.0 + "@typescript-eslint/tsconfig-utils": ^8.48.1 + "@typescript-eslint/types": ^8.48.1 "@vitest/coverage-v8": ^3.1.3 debug: ^4.3.4 rimraf: "*" @@ -6231,12 +6231,12 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/rule-schema-to-typescript-types@8.48.0, @typescript-eslint/rule-schema-to-typescript-types@workspace:*, @typescript-eslint/rule-schema-to-typescript-types@workspace:packages/rule-schema-to-typescript-types": +"@typescript-eslint/rule-schema-to-typescript-types@8.48.1, @typescript-eslint/rule-schema-to-typescript-types@workspace:*, @typescript-eslint/rule-schema-to-typescript-types@workspace:packages/rule-schema-to-typescript-types": version: 0.0.0-use.local resolution: "@typescript-eslint/rule-schema-to-typescript-types@workspace:packages/rule-schema-to-typescript-types" dependencies: - "@typescript-eslint/type-utils": 8.48.0 - "@typescript-eslint/utils": 8.48.0 + "@typescript-eslint/type-utils": 8.48.1 + "@typescript-eslint/utils": 8.48.1 "@vitest/coverage-v8": ^3.1.3 eslint: "*" natural-compare: ^1.4.0 @@ -6246,15 +6246,15 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/rule-tester@8.48.0, @typescript-eslint/rule-tester@workspace:*, @typescript-eslint/rule-tester@workspace:packages/rule-tester": +"@typescript-eslint/rule-tester@8.48.1, @typescript-eslint/rule-tester@workspace:*, @typescript-eslint/rule-tester@workspace:packages/rule-tester": version: 0.0.0-use.local resolution: "@typescript-eslint/rule-tester@workspace:packages/rule-tester" dependencies: "@types/json-stable-stringify-without-jsonify": ^1.0.2 "@types/lodash.merge": 4.6.9 - "@typescript-eslint/parser": 8.48.0 - "@typescript-eslint/typescript-estree": 8.48.0 - "@typescript-eslint/utils": 8.48.0 + "@typescript-eslint/parser": 8.48.1 + "@typescript-eslint/typescript-estree": 8.48.1 + "@typescript-eslint/utils": 8.48.1 "@vitest/coverage-v8": ^3.1.3 ajv: ^6.12.6 eslint: "*" @@ -6269,13 +6269,13 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/scope-manager@8.48.0, @typescript-eslint/scope-manager@^8.46.1, @typescript-eslint/scope-manager@workspace:*, @typescript-eslint/scope-manager@workspace:^, @typescript-eslint/scope-manager@workspace:packages/scope-manager": +"@typescript-eslint/scope-manager@8.48.1, @typescript-eslint/scope-manager@^8.46.1, @typescript-eslint/scope-manager@workspace:*, @typescript-eslint/scope-manager@workspace:^, @typescript-eslint/scope-manager@workspace:packages/scope-manager": version: 0.0.0-use.local resolution: "@typescript-eslint/scope-manager@workspace:packages/scope-manager" dependencies: - "@typescript-eslint/types": 8.48.0 - "@typescript-eslint/typescript-estree": 8.48.0 - "@typescript-eslint/visitor-keys": 8.48.0 + "@typescript-eslint/types": 8.48.1 + "@typescript-eslint/typescript-estree": 8.48.1 + "@typescript-eslint/visitor-keys": 8.48.1 "@vitest/coverage-v8": ^3.1.3 "@vitest/pretty-format": ^3.1.3 eslint: "*" @@ -6286,7 +6286,7 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/tsconfig-utils@8.48.0, @typescript-eslint/tsconfig-utils@^8.48.0, @typescript-eslint/tsconfig-utils@workspace:packages/tsconfig-utils": +"@typescript-eslint/tsconfig-utils@8.48.1, @typescript-eslint/tsconfig-utils@^8.48.1, @typescript-eslint/tsconfig-utils@workspace:packages/tsconfig-utils": version: 0.0.0-use.local resolution: "@typescript-eslint/tsconfig-utils@workspace:packages/tsconfig-utils" dependencies: @@ -6299,14 +6299,14 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/type-utils@8.48.0, @typescript-eslint/type-utils@workspace:*, @typescript-eslint/type-utils@workspace:packages/type-utils": +"@typescript-eslint/type-utils@8.48.1, @typescript-eslint/type-utils@workspace:*, @typescript-eslint/type-utils@workspace:packages/type-utils": version: 0.0.0-use.local resolution: "@typescript-eslint/type-utils@workspace:packages/type-utils" dependencies: - "@typescript-eslint/parser": 8.48.0 - "@typescript-eslint/types": 8.48.0 - "@typescript-eslint/typescript-estree": 8.48.0 - "@typescript-eslint/utils": 8.48.0 + "@typescript-eslint/parser": 8.48.1 + "@typescript-eslint/types": 8.48.1 + "@typescript-eslint/typescript-estree": 8.48.1 + "@typescript-eslint/utils": 8.48.1 "@vitest/coverage-v8": ^3.1.3 ajv: ^6.12.6 debug: ^4.3.4 @@ -6321,7 +6321,7 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/types@8.48.0, @typescript-eslint/types@^8.11.0, @typescript-eslint/types@^8.34.1, @typescript-eslint/types@^8.48.0, @typescript-eslint/types@workspace:*, @typescript-eslint/types@workspace:^, @typescript-eslint/types@workspace:packages/types": +"@typescript-eslint/types@8.48.1, @typescript-eslint/types@^8.11.0, @typescript-eslint/types@^8.34.1, @typescript-eslint/types@^8.48.1, @typescript-eslint/types@workspace:*, @typescript-eslint/types@workspace:^, @typescript-eslint/types@workspace:packages/types": version: 0.0.0-use.local resolution: "@typescript-eslint/types@workspace:packages/types" dependencies: @@ -6395,14 +6395,14 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/typescript-estree@8.48.0, @typescript-eslint/typescript-estree@workspace:*, @typescript-eslint/typescript-estree@workspace:^, @typescript-eslint/typescript-estree@workspace:packages/typescript-estree": +"@typescript-eslint/typescript-estree@8.48.1, @typescript-eslint/typescript-estree@workspace:*, @typescript-eslint/typescript-estree@workspace:^, @typescript-eslint/typescript-estree@workspace:packages/typescript-estree": version: 0.0.0-use.local resolution: "@typescript-eslint/typescript-estree@workspace:packages/typescript-estree" dependencies: - "@typescript-eslint/project-service": 8.48.0 - "@typescript-eslint/tsconfig-utils": 8.48.0 - "@typescript-eslint/types": 8.48.0 - "@typescript-eslint/visitor-keys": 8.48.0 + "@typescript-eslint/project-service": 8.48.1 + "@typescript-eslint/tsconfig-utils": 8.48.1 + "@typescript-eslint/types": 8.48.1 + "@typescript-eslint/visitor-keys": 8.48.1 "@vitest/coverage-v8": ^3.1.3 debug: ^4.3.4 eslint: "*" @@ -6419,14 +6419,14 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/utils@8.48.0, @typescript-eslint/utils@^8.34.1, @typescript-eslint/utils@^8.46.1, @typescript-eslint/utils@workspace:*, @typescript-eslint/utils@workspace:^, @typescript-eslint/utils@workspace:packages/utils": +"@typescript-eslint/utils@8.48.1, @typescript-eslint/utils@^8.34.1, @typescript-eslint/utils@^8.46.1, @typescript-eslint/utils@workspace:*, @typescript-eslint/utils@workspace:^, @typescript-eslint/utils@workspace:packages/utils": version: 0.0.0-use.local resolution: "@typescript-eslint/utils@workspace:packages/utils" dependencies: "@eslint-community/eslint-utils": ^4.7.0 - "@typescript-eslint/scope-manager": 8.48.0 - "@typescript-eslint/types": 8.48.0 - "@typescript-eslint/typescript-estree": 8.48.0 + "@typescript-eslint/scope-manager": 8.48.1 + "@typescript-eslint/types": 8.48.1 + "@typescript-eslint/typescript-estree": 8.48.1 "@vitest/coverage-v8": ^3.1.3 eslint: "*" rimraf: "*" @@ -6438,11 +6438,11 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/visitor-keys@8.48.0, @typescript-eslint/visitor-keys@workspace:*, @typescript-eslint/visitor-keys@workspace:packages/visitor-keys": +"@typescript-eslint/visitor-keys@8.48.1, @typescript-eslint/visitor-keys@workspace:*, @typescript-eslint/visitor-keys@workspace:packages/visitor-keys": version: 0.0.0-use.local resolution: "@typescript-eslint/visitor-keys@workspace:packages/visitor-keys" dependencies: - "@typescript-eslint/types": 8.48.0 + "@typescript-eslint/types": 8.48.1 "@vitest/coverage-v8": ^3.1.3 eslint: "*" eslint-visitor-keys: ^4.2.1 @@ -19984,10 +19984,10 @@ __metadata: version: 0.0.0-use.local resolution: "typescript-eslint@workspace:packages/typescript-eslint" dependencies: - "@typescript-eslint/eslint-plugin": 8.48.0 - "@typescript-eslint/parser": 8.48.0 - "@typescript-eslint/typescript-estree": 8.48.0 - "@typescript-eslint/utils": 8.48.0 + "@typescript-eslint/eslint-plugin": 8.48.1 + "@typescript-eslint/parser": 8.48.1 + "@typescript-eslint/typescript-estree": 8.48.1 + "@typescript-eslint/utils": 8.48.1 "@vitest/coverage-v8": ^3.1.3 eslint: "*" rimraf: "*"