diff --git a/.github/actions/prepare-build/action.yml b/.github/actions/prepare-build/action.yml index d191358d6503..575d5a38e76a 100644 --- a/.github/actions/prepare-build/action.yml +++ b/.github/actions/prepare-build/action.yml @@ -23,8 +23,6 @@ runs: shell: bash run: | yarn nx run types:build - env: - SKIP_AST_SPEC_REBUILD: true - name: Build if: steps['build-cache'].outputs.cache-hit != 'true' @@ -32,5 +30,3 @@ runs: # Website will be built by the Netlify GitHub App run: | yarn nx run-many --target=build --parallel --exclude=website --exclude=website-eslint - env: - SKIP_AST_SPEC_REBUILD: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 75e443872ce2..44a6a7513931 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,34 @@ +## 8.48.0 (2025-11-24) + +### 🚀 Features + +- **eslint-plugin:** [no-redundant-type-constituents] use assignability checking for redundancy checks ([#10744](https://github.com/typescript-eslint/typescript-eslint/pull/10744)) +- **rule-tester:** remove workaround for jest circular structure error ([#11772](https://github.com/typescript-eslint/typescript-eslint/pull/11772)) +- **typescript-estree:** gate all errors behind allowInvalidAST ([#11693](https://github.com/typescript-eslint/typescript-eslint/pull/11693)) +- **typescript-estree:** replace fast-glob with tinyglobby ([#11740](https://github.com/typescript-eslint/typescript-eslint/pull/11740)) + +### 🩹 Fixes + +- **eslint-plugin:** [consistent-generic-constructors] ignore when constructor is typed array ([#10477](https://github.com/typescript-eslint/typescript-eslint/pull/10477)) +- **scope-manager:** change unhelpful `aaa` error message and change `analyze` to expects `Program` ([#11747](https://github.com/typescript-eslint/typescript-eslint/pull/11747)) +- **typescript-estree:** infers singleRun as true for project service ([#11327](https://github.com/typescript-eslint/typescript-eslint/pull/11327)) +- **typescript-estree:** disallow binding patterns in parameter properties ([#11760](https://github.com/typescript-eslint/typescript-eslint/pull/11760)) + +### ❤️ Thank You + +- Ben McCann @benmccann +- Dima Barabash @dbarabashh +- fisker Cheung @fisker +- James Henry @JamesHenry +- JamesHenry @JamesHenry +- Josh Goldberg +- Josh Goldberg ✨ +- Kirk Waiblinger @kirkwaiblinger +- mdm317 @gen-ip-1 +- Younsang Na @nayounsang + +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.47.0 (2025-11-17) ### 🚀 Features diff --git a/nx.json b/nx.json index b0ac6867484c..0458dd7a861a 100644 --- a/nx.json +++ b/nx.json @@ -15,11 +15,11 @@ } }, { - "plugin": "@nx/vite/plugin", + "plugin": "@nx/vitest", "exclude": ["*"], "options": { "testTargetName": "test", - "typecheckTargetName": "vite:typecheck" + "typecheckTargetName": "vitest:typecheck" } } ], @@ -40,7 +40,8 @@ } }, "version": { - "conventionalCommits": true + "conventionalCommits": true, + "preserveMatchingDependencyRanges": false } }, "targetDefaults": { diff --git a/package.json b/package.json index fc18c47878f6..ee1fc0815fd7 100644 --- a/package.json +++ b/package.json @@ -56,10 +56,10 @@ "@eslint/compat": "^1.2.4", "@eslint/eslintrc": "^3.2.0", "@eslint/js": "^9.26.0", - "@nx/devkit": "21.4.1", - "@nx/js": "21.4.1", - "@nx/vite": "21.4.1", - "@nx/workspace": "21.4.1", + "@nx/devkit": "22.1.1", + "@nx/js": "22.1.1", + "@nx/vitest": "22.1.1", + "@nx/workspace": "22.1.1", "@swc/core": "^1.4.12", "@types/debug": "^4.1.12", "@types/eslint-plugin-jsx-a11y": "^6.10.0", @@ -95,14 +95,14 @@ "knip": "^5.41.1", "lint-staged": "^15.2.2", "markdownlint-cli": "^0.45.0", - "nx": "21.4.1", + "nx": "22.1.1", "prettier": "3.6.2", "rimraf": "^5.0.5", "semver": "7.7.0", "tsx": "*", "typescript": ">=4.8.4 <6.0.0", "typescript-eslint": "workspace:^", - "vite": "^6.3.5", + "vite": "7.2.4", "vitest": "^3.1.3", "yargs": "17.7.2", "yarn-berry-deduplicate": "^6.1.3" diff --git a/packages/ast-spec/CHANGELOG.md b/packages/ast-spec/CHANGELOG.md index 3e0661fa9fc8..c82ce9b0286b 100644 --- a/packages/ast-spec/CHANGELOG.md +++ b/packages/ast-spec/CHANGELOG.md @@ -1,3 +1,17 @@ +## 8.48.0 (2025-11-24) + +### 🩹 Fixes + +- **typescript-estree:** disallow binding patterns in parameter properties ([#11760](https://github.com/typescript-eslint/typescript-eslint/pull/11760)) + +### ❤️ Thank You + +- Dima Barabash @dbarabashh +- JamesHenry @JamesHenry +- Josh Goldberg + +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.47.0 (2025-11-17) This was a version bump only for ast-spec to align it with other projects, there were no code changes. diff --git a/packages/ast-spec/package.json b/packages/ast-spec/package.json index 5ce878af83fe..f7f3f4773522 100644 --- a/packages/ast-spec/package.json +++ b/packages/ast-spec/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/ast-spec", - "version": "8.47.0", + "version": "8.48.0", "description": "Complete specification for the TypeScript-ESTree AST", "private": true, "keywords": [ diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-import-type-with-type-parameters-in-type-reference/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-import-type-with-type-parameters-in-type-reference/snapshots/1-TSESTree-AST.shot index 50d6d1351243..93af449d7fc4 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-import-type-with-type-parameters-in-type-reference/snapshots/1-TSESTree-AST.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-import-type-with-type-parameters-in-type-reference/snapshots/1-TSESTree-AST.shot @@ -23,26 +23,6 @@ Program { params: [ TSImportType { type: "TSImportType", - argument: TSLiteralType { - type: "TSLiteralType", - literal: Literal { - type: "Literal", - raw: "''", - value: "", - - range: [91, 93], - loc: { - start: { column: 18, line: 3 }, - end: { column: 20, line: 3 }, - }, - }, - - range: [91, 93], - loc: { - start: { column: 18, line: 3 }, - end: { column: 20, line: 3 }, - }, - }, options: null, qualifier: Identifier { type: "Identifier", @@ -56,6 +36,17 @@ Program { end: { column: 23, line: 3 }, }, }, + source: Literal { + type: "Literal", + raw: "''", + value: "", + + range: [91, 93], + loc: { + start: { column: 18, line: 3 }, + end: { column: 20, line: 3 }, + }, + }, typeArguments: TSTypeParameterInstantiation { type: "TSTypeParameterInstantiation", params: [ diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-import-type-with-type-parameters-in-type-reference/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-import-type-with-type-parameters-in-type-reference/snapshots/5-AST-Alignment-AST.shot index 53daa9433108..0adc61476321 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-import-type-with-type-parameters-in-type-reference/snapshots/5-AST-Alignment-AST.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-import-type-with-type-parameters-in-type-reference/snapshots/5-AST-Alignment-AST.shot @@ -43,30 +43,17 @@ Snapshot Diff: params: Array [ TSImportType { type: 'TSImportType', -- argument: TSLiteralType { -- type: 'TSLiteralType', -- literal: Literal { -- type: 'Literal', -- raw: '\'\'', -- value: '', -- -- range: [91, 93], -- loc: { -- start: { column: 18, line: 3 }, -- end: { column: 20, line: 3 }, -- }, -- }, + argument: Literal { + type: 'Literal', + raw: '\'\'', + value: '', - - range: [91, 93], - loc: { - start: { column: 18, line: 3 }, - end: { column: 20, line: 3 }, - }, - }, ++ ++ range: [91, 93], ++ loc: { ++ start: { column: 18, line: 3 }, ++ end: { column: 20, line: 3 }, ++ }, ++ }, options: null, qualifier: Identifier { type: 'Identifier', @@ -78,6 +65,17 @@ Snapshot Diff: loc: { start: { column: 22, line: 3 }, end: { column: 23, line: 3 }, +- }, +- }, +- source: Literal { +- type: 'Literal', +- raw: '\'\'', +- value: '', +- +- range: [91, 93], +- loc: { +- start: { column: 18, line: 3 }, +- end: { column: 20, line: 3 }, }, }, - typeArguments: TSTypeParameterInstantiation { diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-import-type/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-import-type/snapshots/1-TSESTree-AST.shot index ae79fc4a18d2..5de8f25f9ede 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-import-type/snapshots/1-TSESTree-AST.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-import-type/snapshots/1-TSESTree-AST.shot @@ -20,19 +20,12 @@ Program { type: "TSTypeQuery", exprName: TSImportType { type: "TSImportType", - argument: TSLiteralType { - type: "TSLiteralType", - literal: Literal { - type: "Literal", - raw: "'A'", - value: "A", - - range: [96, 99], - loc: { - start: { column: 23, line: 3 }, - end: { column: 26, line: 3 }, - }, - }, + options: null, + qualifier: null, + source: Literal { + type: "Literal", + raw: "'A'", + value: "A", range: [96, 99], loc: { @@ -40,8 +33,6 @@ Program { end: { column: 26, line: 3 }, }, }, - options: null, - qualifier: null, typeArguments: null, range: [89, 100], @@ -81,26 +72,6 @@ Program { }, typeAnnotation: TSImportType { type: "TSImportType", - argument: TSLiteralType { - type: "TSLiteralType", - literal: Literal { - type: "Literal", - raw: "'B'", - value: "B", - - range: [118, 121], - loc: { - start: { column: 16, line: 4 }, - end: { column: 19, line: 4 }, - }, - }, - - range: [118, 121], - loc: { - start: { column: 16, line: 4 }, - end: { column: 19, line: 4 }, - }, - }, options: null, qualifier: Identifier { type: "Identifier", @@ -114,6 +85,17 @@ Program { end: { column: 22, line: 4 }, }, }, + source: Literal { + type: "Literal", + raw: "'B'", + value: "B", + + range: [118, 121], + loc: { + start: { column: 16, line: 4 }, + end: { column: 19, line: 4 }, + }, + }, typeArguments: TSTypeParameterInstantiation { type: "TSTypeParameterInstantiation", params: [ diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-import-type/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-import-type/snapshots/5-AST-Alignment-AST.shot index 133f7bdd66bc..51f2757059b3 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-import-type/snapshots/5-AST-Alignment-AST.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-import-type/snapshots/5-AST-Alignment-AST.shot @@ -27,33 +27,23 @@ Snapshot Diff: type: 'TSTypeQuery', exprName: TSImportType { type: 'TSImportType', -- argument: TSLiteralType { -- type: 'TSLiteralType', -- literal: Literal { -- type: 'Literal', -- raw: '\'A\'', -- value: 'A', +- options: null, +- qualifier: null, +- source: Literal { + argument: Literal { -+ type: 'Literal', -+ raw: '\'A\'', -+ value: 'A', + type: 'Literal', + raw: '\'A\'', + value: 'A', -- range: [96, 99], -- loc: { -- start: { column: 23, line: 3 }, -- end: { column: 26, line: 3 }, -- }, -- }, -- range: [96, 99], loc: { start: { column: 23, line: 3 }, end: { column: 26, line: 3 }, }, }, - options: null, - qualifier: null, - typeArguments: null, ++ options: null, ++ qualifier: null, range: [89, 100], loc: { @@ -92,30 +82,17 @@ Snapshot Diff: }, typeAnnotation: TSImportType { type: 'TSImportType', -- argument: TSLiteralType { -- type: 'TSLiteralType', -- literal: Literal { -- type: 'Literal', -- raw: '\'B\'', -- value: 'B', -- -- range: [118, 121], -- loc: { -- start: { column: 16, line: 4 }, -- end: { column: 19, line: 4 }, -- }, -- }, + argument: Literal { + type: 'Literal', + raw: '\'B\'', + value: 'B', - - range: [118, 121], - loc: { - start: { column: 16, line: 4 }, - end: { column: 19, line: 4 }, - }, - }, ++ ++ range: [118, 121], ++ loc: { ++ start: { column: 16, line: 4 }, ++ end: { column: 19, line: 4 }, ++ }, ++ }, options: null, qualifier: Identifier { type: 'Identifier', @@ -129,6 +106,17 @@ Snapshot Diff: end: { column: 22, line: 4 }, }, }, +- source: Literal { +- type: 'Literal', +- raw: '\'B\'', +- value: 'B', +- +- range: [118, 121], +- loc: { +- start: { column: 16, line: 4 }, +- end: { column: 19, line: 4 }, +- }, +- }, - typeArguments: TSTypeParameterInstantiation { + typeParameters: TSTypeParameterInstantiation { type: 'TSTypeParameterInstantiation', diff --git a/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/array-binding-pattern/fixture.ts b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/array-binding-pattern/fixture.ts new file mode 100644 index 000000000000..2fbce35f8c2b --- /dev/null +++ b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/array-binding-pattern/fixture.ts @@ -0,0 +1 @@ +class Test { constructor(private [foo] = [1]) {} } diff --git a/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/array-binding-pattern/snapshots/1-TSESTree-Error.shot b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/array-binding-pattern/snapshots/1-TSESTree-Error.shot new file mode 100644 index 000000000000..586ccf1774a8 --- /dev/null +++ b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/array-binding-pattern/snapshots/1-TSESTree-Error.shot @@ -0,0 +1,7 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`AST Fixtures > parameter > TSParameterProperty > _error_ > array-binding-pattern > TSESTree - Error`] +TSError +> 1 | class Test { constructor(private [foo] = [1]) {} } + | ^^^^^^^ A parameter property may not be declared using a binding pattern. + 2 | diff --git a/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/array-binding-pattern/snapshots/2-Babel-Error.shot b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/array-binding-pattern/snapshots/2-Babel-Error.shot new file mode 100644 index 000000000000..7d93eabb945b --- /dev/null +++ b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/array-binding-pattern/snapshots/2-Babel-Error.shot @@ -0,0 +1,4 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`AST Fixtures > parameter > TSParameterProperty > _error_ > array-binding-pattern > Babel - Error`] +NO ERROR diff --git a/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/array-binding-pattern/snapshots/3-Alignment-Error.shot b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/array-binding-pattern/snapshots/3-Alignment-Error.shot new file mode 100644 index 000000000000..7538155bd744 --- /dev/null +++ b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/array-binding-pattern/snapshots/3-Alignment-Error.shot @@ -0,0 +1,4 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`AST Fixtures > parameter > TSParameterProperty > _error_ > array-binding-pattern > Error Alignment`] +TSESTree errored but Babel didn't diff --git a/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/object-binding-pattern/fixture.ts b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/object-binding-pattern/fixture.ts new file mode 100644 index 000000000000..bbe335cc761c --- /dev/null +++ b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/object-binding-pattern/fixture.ts @@ -0,0 +1 @@ +class Test { constructor(private { bar } = { bar: 1 }) {} } diff --git a/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/object-binding-pattern/snapshots/1-TSESTree-Error.shot b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/object-binding-pattern/snapshots/1-TSESTree-Error.shot new file mode 100644 index 000000000000..d9ff1ab599e6 --- /dev/null +++ b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/object-binding-pattern/snapshots/1-TSESTree-Error.shot @@ -0,0 +1,7 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`AST Fixtures > parameter > TSParameterProperty > _error_ > object-binding-pattern > TSESTree - Error`] +TSError +> 1 | class Test { constructor(private { bar } = { bar: 1 }) {} } + | ^^^^^^^ A parameter property may not be declared using a binding pattern. + 2 | diff --git a/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/object-binding-pattern/snapshots/2-Babel-Error.shot b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/object-binding-pattern/snapshots/2-Babel-Error.shot new file mode 100644 index 000000000000..431930916f56 --- /dev/null +++ b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/object-binding-pattern/snapshots/2-Babel-Error.shot @@ -0,0 +1,4 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`AST Fixtures > parameter > TSParameterProperty > _error_ > object-binding-pattern > Babel - Error`] +NO ERROR diff --git a/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/object-binding-pattern/snapshots/3-Alignment-Error.shot b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/object-binding-pattern/snapshots/3-Alignment-Error.shot new file mode 100644 index 000000000000..c0caca49caaf --- /dev/null +++ b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/object-binding-pattern/snapshots/3-Alignment-Error.shot @@ -0,0 +1,4 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`AST Fixtures > parameter > TSParameterProperty > _error_ > object-binding-pattern > Error Alignment`] +TSESTree errored but Babel didn't diff --git a/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/rest-element/fixture.ts b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/rest-element/fixture.ts new file mode 100644 index 000000000000..20c00fed1e70 --- /dev/null +++ b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/rest-element/fixture.ts @@ -0,0 +1 @@ +class Test { constructor(private ...baz) {} } diff --git a/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/rest-element/snapshots/1-TSESTree-Error.shot b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/rest-element/snapshots/1-TSESTree-Error.shot new file mode 100644 index 000000000000..44a9cb60e261 --- /dev/null +++ b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/rest-element/snapshots/1-TSESTree-Error.shot @@ -0,0 +1,7 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`AST Fixtures > parameter > TSParameterProperty > _error_ > rest-element > TSESTree - Error`] +TSError +> 1 | class Test { constructor(private ...baz) {} } + | ^^^^^^^ A parameter property cannot be a rest parameter. + 2 | diff --git a/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/rest-element/snapshots/2-Babel-Error.shot b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/rest-element/snapshots/2-Babel-Error.shot new file mode 100644 index 000000000000..babf62db89b0 --- /dev/null +++ b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/rest-element/snapshots/2-Babel-Error.shot @@ -0,0 +1,8 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`AST Fixtures > parameter > TSParameterProperty > _error_ > rest-element > Babel - Error`] +BabelError +> 1 | class Test { constructor(private ...baz) {} } + | ^ Unexpected token (1:33) + 2 | + diff --git a/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/rest-element/snapshots/3-Alignment-Error.shot b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/rest-element/snapshots/3-Alignment-Error.shot new file mode 100644 index 000000000000..86b1efbb566c --- /dev/null +++ b/packages/ast-spec/src/parameter/TSParameterProperty/fixtures/_error_/rest-element/snapshots/3-Alignment-Error.shot @@ -0,0 +1,4 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`AST Fixtures > parameter > TSParameterProperty > _error_ > rest-element > Error Alignment`] +Both errored diff --git a/packages/ast-spec/src/parameter/TSParameterProperty/spec.ts b/packages/ast-spec/src/parameter/TSParameterProperty/spec.ts index 2471c9985dcb..8dc300ea11e0 100644 --- a/packages/ast-spec/src/parameter/TSParameterProperty/spec.ts +++ b/packages/ast-spec/src/parameter/TSParameterProperty/spec.ts @@ -1,17 +1,20 @@ import type { AST_NODE_TYPES } from '../../ast-node-types'; import type { Accessibility } from '../../base/Accessibility'; import type { BaseNode } from '../../base/BaseNode'; +import type { Identifier } from '../../expression/Identifier/spec'; import type { Decorator } from '../../special/Decorator/spec'; -import type { BindingName } from '../../unions/BindingName'; import type { AssignmentPattern } from '../AssignmentPattern/spec'; -import type { RestElement } from '../RestElement/spec'; + +type ParameterPropertyParameter = + | (AssignmentPattern & { left: Identifier }) + | Identifier; export interface TSParameterProperty extends BaseNode { type: AST_NODE_TYPES.TSParameterProperty; accessibility: Accessibility | undefined; decorators: Decorator[]; override: boolean; - parameter: AssignmentPattern | BindingName | RestElement; + parameter: ParameterPropertyParameter; readonly: boolean; static: boolean; } diff --git a/packages/ast-spec/src/type/TSImportType/fixtures/type-import-type-with-import-attributes-with/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/type/TSImportType/fixtures/type-import-type-with-import-attributes-with/snapshots/1-TSESTree-AST.shot index e20487325971..487e796a9336 100644 --- a/packages/ast-spec/src/type/TSImportType/fixtures/type-import-type-with-import-attributes-with/snapshots/1-TSESTree-AST.shot +++ b/packages/ast-spec/src/type/TSImportType/fixtures/type-import-type-with-import-attributes-with/snapshots/1-TSESTree-AST.shot @@ -18,26 +18,6 @@ Program { }, typeAnnotation: TSImportType { type: "TSImportType", - argument: TSLiteralType { - type: "TSLiteralType", - literal: Literal { - type: "Literal", - raw: "'A'", - value: "A", - - range: [16, 19], - loc: { - start: { column: 16, line: 1 }, - end: { column: 19, line: 1 }, - }, - }, - - range: [16, 19], - loc: { - start: { column: 16, line: 1 }, - end: { column: 19, line: 1 }, - }, - }, options: ObjectExpression { type: "ObjectExpression", properties: [ @@ -124,6 +104,17 @@ Program { }, }, qualifier: null, + source: Literal { + type: "Literal", + raw: "'A'", + value: "A", + + range: [16, 19], + loc: { + start: { column: 16, line: 1 }, + end: { column: 19, line: 1 }, + }, + }, typeArguments: null, range: [9, 48], diff --git a/packages/ast-spec/src/type/TSImportType/fixtures/type-import-type-with-import-attributes-with/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/type/TSImportType/fixtures/type-import-type-with-import-attributes-with/snapshots/5-AST-Alignment-AST.shot index 668b4bceacd6..909e0b9be274 100644 --- a/packages/ast-spec/src/type/TSImportType/fixtures/type-import-type-with-import-attributes-with/snapshots/5-AST-Alignment-AST.shot +++ b/packages/ast-spec/src/type/TSImportType/fixtures/type-import-type-with-import-attributes-with/snapshots/5-AST-Alignment-AST.shot @@ -25,30 +25,17 @@ Snapshot Diff: }, typeAnnotation: TSImportType { type: 'TSImportType', -- argument: TSLiteralType { -- type: 'TSLiteralType', -- literal: Literal { -- type: 'Literal', -- raw: '\'A\'', -- value: 'A', + argument: Literal { + type: 'Literal', + raw: '\'A\'', + value: 'A', - -- range: [16, 19], -- loc: { -- start: { column: 16, line: 1 }, -- end: { column: 19, line: 1 }, -- }, -- }, -- - range: [16, 19], - loc: { - start: { column: 16, line: 1 }, - end: { column: 19, line: 1 }, - }, - }, ++ ++ range: [16, 19], ++ loc: { ++ start: { column: 16, line: 1 }, ++ end: { column: 19, line: 1 }, ++ }, ++ }, options: ObjectExpression { type: 'ObjectExpression', properties: Array [ @@ -135,6 +122,17 @@ Snapshot Diff: }, }, qualifier: null, +- source: Literal { +- type: 'Literal', +- raw: '\'A\'', +- value: 'A', +- +- range: [16, 19], +- loc: { +- start: { column: 16, line: 1 }, +- end: { column: 19, line: 1 }, +- }, +- }, - typeArguments: null, range: [9, 48], diff --git a/packages/ast-spec/src/type/TSImportType/fixtures/type-import-type-with-trailing-comma-in-import-attributes/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/type/TSImportType/fixtures/type-import-type-with-trailing-comma-in-import-attributes/snapshots/1-TSESTree-AST.shot index f1f332ffa5de..1c448268bda4 100644 --- a/packages/ast-spec/src/type/TSImportType/fixtures/type-import-type-with-trailing-comma-in-import-attributes/snapshots/1-TSESTree-AST.shot +++ b/packages/ast-spec/src/type/TSImportType/fixtures/type-import-type-with-trailing-comma-in-import-attributes/snapshots/1-TSESTree-AST.shot @@ -18,26 +18,6 @@ Program { }, typeAnnotation: TSImportType { type: "TSImportType", - argument: TSLiteralType { - type: "TSLiteralType", - literal: Literal { - type: "Literal", - raw: ""A"", - value: "A", - - range: [28, 31], - loc: { - start: { column: 28, line: 1 }, - end: { column: 31, line: 1 }, - }, - }, - - range: [28, 31], - loc: { - start: { column: 28, line: 1 }, - end: { column: 31, line: 1 }, - }, - }, options: ObjectExpression { type: "ObjectExpression", properties: [ @@ -123,6 +103,17 @@ Program { }, }, qualifier: null, + source: Literal { + type: "Literal", + raw: ""A"", + value: "A", + + range: [28, 31], + loc: { + start: { column: 28, line: 1 }, + end: { column: 31, line: 1 }, + }, + }, typeArguments: null, range: [21, 78], diff --git a/packages/ast-spec/src/type/TSImportType/fixtures/type-import-type-with-trailing-comma-in-import-attributes/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/type/TSImportType/fixtures/type-import-type-with-trailing-comma-in-import-attributes/snapshots/5-AST-Alignment-AST.shot index 4cf4abde9c9f..b05876842380 100644 --- a/packages/ast-spec/src/type/TSImportType/fixtures/type-import-type-with-trailing-comma-in-import-attributes/snapshots/5-AST-Alignment-AST.shot +++ b/packages/ast-spec/src/type/TSImportType/fixtures/type-import-type-with-trailing-comma-in-import-attributes/snapshots/5-AST-Alignment-AST.shot @@ -25,30 +25,17 @@ Snapshot Diff: }, typeAnnotation: TSImportType { type: 'TSImportType', -- argument: TSLiteralType { -- type: 'TSLiteralType', -- literal: Literal { -- type: 'Literal', -- raw: '"A"', -- value: 'A', + argument: Literal { + type: 'Literal', + raw: '"A"', + value: 'A', - -- range: [28, 31], -- loc: { -- start: { column: 28, line: 1 }, -- end: { column: 31, line: 1 }, -- }, -- }, -- - range: [28, 31], - loc: { - start: { column: 28, line: 1 }, - end: { column: 31, line: 1 }, - }, - }, ++ ++ range: [28, 31], ++ loc: { ++ start: { column: 28, line: 1 }, ++ end: { column: 31, line: 1 }, ++ }, ++ }, options: ObjectExpression { type: 'ObjectExpression', properties: Array [ @@ -134,6 +121,17 @@ Snapshot Diff: }, }, qualifier: null, +- source: Literal { +- type: 'Literal', +- raw: '"A"', +- value: 'A', +- +- range: [28, 31], +- loc: { +- start: { column: 28, line: 1 }, +- end: { column: 31, line: 1 }, +- }, +- }, - typeArguments: null, range: [21, 78], diff --git a/packages/ast-spec/src/type/TSImportType/spec.ts b/packages/ast-spec/src/type/TSImportType/spec.ts index 23bcfb689f93..37e180c67c42 100644 --- a/packages/ast-spec/src/type/TSImportType/spec.ts +++ b/packages/ast-spec/src/type/TSImportType/spec.ts @@ -1,5 +1,6 @@ import type { AST_NODE_TYPES } from '../../ast-node-types'; import type { BaseNode } from '../../base/BaseNode'; +import type { StringLiteral } from '../../expression/literal/StringLiteral/spec'; import type { ObjectExpression } from '../../expression/ObjectExpression/spec'; import type { TSTypeParameterInstantiation } from '../../special/TSTypeParameterInstantiation/spec'; import type { EntityName } from '../../unions/EntityName'; @@ -7,8 +8,10 @@ import type { TypeNode } from '../../unions/TypeNode'; export interface TSImportType extends BaseNode { type: AST_NODE_TYPES.TSImportType; + /** @deprecated Use {@link `source`} instead. */ argument: TypeNode; options: ObjectExpression | null; qualifier: EntityName | null; + source: StringLiteral; typeArguments: TSTypeParameterInstantiation | null; } diff --git a/packages/ast-spec/tests/fixtures-with-differences-errors.shot b/packages/ast-spec/tests/fixtures-with-differences-errors.shot index cb157b9d2bb9..4f9e17a13c8b 100644 --- a/packages/ast-spec/tests/fixtures-with-differences-errors.shot +++ b/packages/ast-spec/tests/fixtures-with-differences-errors.shot @@ -77,6 +77,8 @@ exports[`AST Fixtures > List fixtures with Error differences`] "declaration/VariableDeclaration/fixtures/_error_/var-id-definite-type-init/fixture.ts", "element/AccessorProperty/fixtures/_error_/modifier-abstract-accessor-with-value/fixture.ts", "legacy-fixtures/basics/fixtures/_error_/abstract-class-with-abstract-constructor/fixture.ts", + "parameter/TSParameterProperty/fixtures/_error_/array-binding-pattern/fixture.ts", + "parameter/TSParameterProperty/fixtures/_error_/object-binding-pattern/fixture.ts", "statement/ForOfStatement/fixtures/_error_/decl-definite-using/fixture.ts", "statement/ForOfStatement/fixtures/_error_/decl-definite/fixture.ts", "statement/ForOfStatement/fixtures/_error_/decl-type/fixture.ts" diff --git a/packages/eslint-plugin-internal/tsconfig.json b/packages/eslint-plugin-internal/tsconfig.json index 9df0fb2d2e38..d4d0929e1955 100644 --- a/packages/eslint-plugin-internal/tsconfig.json +++ b/packages/eslint-plugin-internal/tsconfig.json @@ -3,18 +3,6 @@ "files": [], "include": [], "references": [ - { - "path": "../type-utils" - }, - { - "path": "../scope-manager" - }, - { - "path": "../rule-tester" - }, - { - "path": "../utils" - }, { "path": "./tsconfig.build.json" }, diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index 7fa6467aada1..4dea8bb550dc 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -1,3 +1,23 @@ +## 8.48.0 (2025-11-24) + +### 🚀 Features + +- **eslint-plugin:** [no-redundant-type-constituents] use assignability checking for redundancy checks ([#10744](https://github.com/typescript-eslint/typescript-eslint/pull/10744)) + +### 🩹 Fixes + +- **typescript-estree:** disallow binding patterns in parameter properties ([#11760](https://github.com/typescript-eslint/typescript-eslint/pull/11760)) +- **eslint-plugin:** [consistent-generic-constructors] ignore when constructor is typed array ([#10477](https://github.com/typescript-eslint/typescript-eslint/pull/10477)) + +### ❤️ Thank You + +- Dima Barabash @dbarabashh +- JamesHenry @JamesHenry +- Josh Goldberg +- mdm317 @gen-ip-1 + +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.47.0 (2025-11-17) ### 🚀 Features diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 522d8d846ea0..c452887ca310 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin", - "version": "8.47.0", + "version": "8.48.0", "description": "TypeScript plugin for ESLint", "files": [ "dist", @@ -59,10 +59,10 @@ }, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.47.0", - "@typescript-eslint/type-utils": "8.47.0", - "@typescript-eslint/utils": "8.47.0", - "@typescript-eslint/visitor-keys": "8.47.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", "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.47.0", - "@typescript-eslint/rule-tester": "8.47.0", + "@typescript-eslint/rule-schema-to-typescript-types": "8.48.0", + "@typescript-eslint/rule-tester": "8.48.0", "@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.47.0", + "@typescript-eslint/parser": "^8.48.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" }, diff --git a/packages/eslint-plugin/src/configs/eslint-recommended-raw.ts b/packages/eslint-plugin/src/configs/eslint-recommended-raw.ts index f2e67a7bd382..c9f3fb5c9729 100644 --- a/packages/eslint-plugin/src/configs/eslint-recommended-raw.ts +++ b/packages/eslint-plugin/src/configs/eslint-recommended-raw.ts @@ -27,8 +27,13 @@ const config = ( 'no-dupe-keys': 'off', // ts(1117) 'no-func-assign': 'off', // ts(2630) 'no-import-assign': 'off', // ts(2632) & ts(2540) - // TODO - remove this once we no longer support ESLint v8 'no-new-native-nonconstructor': 'off', // ts(7009) + // "no-new-symbol" was deprecated in ESLint 9.0.0 and will be removed in + // ESLint v11.0.0. See: + // https://eslint.org/docs/latest/rules/no-new-symbol + // We need to keep the rule disabled until TSESLint drops support for + // ESlint 8. See: + // https://github.com/typescript-eslint/typescript-eslint/pull/8895 'no-new-symbol': 'off', // ts(7009) 'no-obj-calls': 'off', // ts(2349) 'no-redeclare': 'off', // ts(2451) diff --git a/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts b/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts index a26f1422460e..8ba1be086c19 100644 --- a/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts +++ b/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts @@ -2,11 +2,28 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { createRule, nullThrows, NullThrowsReasons } from '../util'; +import { + createRule, + isReferenceToGlobalFunction, + nullThrows, + NullThrowsReasons, +} from '../util'; export type MessageIds = 'preferConstructor' | 'preferTypeAnnotation'; export type Options = ['constructor' | 'type-annotation']; +const builtInArrays = new Set([ + 'Float32Array', + 'Float64Array', + 'Int16Array', + 'Int32Array', + 'Int8Array', + 'Uint16Array', + 'Uint32Array', + 'Uint8Array', + 'Uint8ClampedArray', +]); + export default createRule({ name: 'consistent-generic-constructors', meta: { @@ -63,6 +80,18 @@ export default createRule({ ); } } + + function isBuiltInArray(typeName: TSESTree.Identifier) { + return ( + builtInArrays.has(typeName.name) && + isReferenceToGlobalFunction( + typeName.name, + typeName, + context.sourceCode, + ) + ); + } + const [lhsName, rhs] = getLHSRHS(); const lhs = lhsName.typeAnnotation?.typeAnnotation; @@ -77,7 +106,8 @@ export default createRule({ lhs && (lhs.type !== AST_NODE_TYPES.TSTypeReference || lhs.typeName.type !== AST_NODE_TYPES.Identifier || - lhs.typeName.name !== rhs.callee.name) + lhs.typeName.name !== rhs.callee.name || + isBuiltInArray(lhs.typeName)) ) { return; } diff --git a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts index d1b6f8ea3422..b6ca8af38488 100644 --- a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts +++ b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts @@ -359,19 +359,10 @@ export default createRule({ node: TSESTree.TSParameterProperty, ): void { const nodeType = 'parameter property'; - // HAS to be an identifier or assignment or TSC will throw - if ( - node.parameter.type !== AST_NODE_TYPES.Identifier && - node.parameter.type !== AST_NODE_TYPES.AssignmentPattern - ) { - return; - } - const nodeName = node.parameter.type === AST_NODE_TYPES.Identifier ? node.parameter.name - : // has to be an Identifier or TSC will throw an error - (node.parameter.left as TSESTree.Identifier).name; + : (node.parameter.left as TSESTree.Identifier).name; switch (paramPropCheck) { case 'explicit': { 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 2070ba9a869d..0c1e2e27a813 100644 --- a/packages/eslint-plugin/src/rules/no-redundant-type-constituents.ts +++ b/packages/eslint-plugin/src/rules/no-redundant-type-constituents.ts @@ -1,76 +1,32 @@ -import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils'; +import type { TSESTree } from '@typescript-eslint/utils'; + +import { AST_NODE_TYPES } 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 TypeNodeWithValue { - literalValue: unknown; - typeNode: TSESTree.TypeNode; +interface TypeWithName { + type: ts.Type; + typeName: string; +} + +interface TypeRedundancyRelation { + redundantTypeWithName: TypeWithName; + nonRedundantTypeWithName: TypeWithName; +} + +interface TypeWithNameAndParentNode extends TypeWithName { + parentTypeNode: TSESTree.TypeNode; } function addToMapGroup( @@ -87,107 +43,395 @@ function addToMapGroup( } } -function describeLiteralType(type: ts.Type): string { - if (type.isStringLiteral()) { - return JSON.stringify(type.value); +function isUnionNodeInsideReturnType(node: TSESTree.TSUnionType): boolean { + if (node.parent.type === AST_NODE_TYPES.TSUnionType) { + return isUnionNodeInsideReturnType(node.parent); } + return ( + node.parent.type === AST_NODE_TYPES.TSTypeAnnotation && + isFunctionOrFunctionType(node.parent.parent) + ); +} - if (isTypeBigIntLiteralType(type)) { - return `${type.value.negative ? '-' : ''}${type.value.base10Value}n`; - } +function isObjectOrIntersectionType( + type: ts.Type, +): type is ts.IntersectionType | ts.ObjectType { + return tsutils.isObjectType(type) || tsutils.isIntersectionType(type); +} - if (type.isLiteral()) { - // eslint-disable-next-line @typescript-eslint/no-base-to-string - return type.value.toString(); +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), + ); } + return true; +} - if (tsutils.isIntrinsicErrorType(type) && type.aliasSymbol) { - return type.aliasSymbol.escapedName.toString(); +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 (isTypeAnyType(type)) { - return 'any'; + 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 (isTypeNeverType(type)) { - return 'never'; + 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 (isTypeUnknownType(type)) { - return 'unknown'; + 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 (tsutils.isObjectType(sourceType) && tsutils.isObjectType(targetType)) { + const sourceProps = sourceType.getProperties(); + const targetProps = targetType.getProperties(); + if (targetProps.length === 0) { + return false; + } - if (isTypeTemplateLiteralType(type)) { - return 'template literal type'; + 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; } + return checker.isTypeAssignableTo(sourceType, targetType); +} - if (isTypeBigIntLiteralType(type)) { - return `${type.value.negative ? '-' : ''}${type.value.base10Value}n`; +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 (tsutils.isTrueLiteralType(type)) { - return 'true'; + 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 (tsutils.isFalseLiteralType(type)) { - return 'false'; + 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 ( + 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; + } - return 'literal type'; -} + for (const targetProp of targetProps) { + const sourceProp = sourceProps.find( + prop => prop.getName() === targetProp.getName(), + ); -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'; + if (!sourceProp) { + return false; } - } - return 'literal type'; + const sourcePropType = checker.getTypeOfSymbol(sourceProp); + const targetPropType = checker.getTypeOfSymbol(targetProp); + + const targetPropTypeIsRedundant = isTargetTypeRedundantInUnion( + sourcePropType, + targetPropType, + checker, + ); + if (!targetPropTypeIsRedundant) { + return false; + } + } + return true; + } + return checker.isTypeAssignableTo(targetType, sourceType); } +function mergeTypeNames( + typeWithNames: TypeWithName[], + operator: '&' | '|', +): string { + if (typeWithNames.length === 1) { + return typeWithNames[0].typeName; + } -function isNodeInsideReturnType(node: TSESTree.TSUnionType): boolean { - return ( - node.parent.type === AST_NODE_TYPES.TSTypeAnnotation && - isFunctionOrFunctionType(node.parent.parent) - ); + const wrapType = (typeWithName: TypeWithName) => { + if (operator === '|' && typeWithName.type.isIntersection()) { + return `(${typeWithName.typeName})`; + } + if (operator === '&' && typeWithName.type.isUnion()) { + return `(${typeWithName.typeName})`; + } + return typeWithName.typeName; + }; + + return typeWithNames.map(wrapType).join(` ${operator} `); } -/** - * @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); +function getGroupTypeRelationsByNonRedundantType( + typeRedundancyRelations: TypeRedundancyRelation[], +) { + const groups = new Map(); + + for (const typeRedundancyRelation of typeRedundancyRelations) { + addToMapGroup( + groups, + typeRedundancyRelation.nonRedundantTypeWithName.type, + typeRedundancyRelation, + ); + } + return groups; } export default createRule({ @@ -202,83 +446,102 @@ 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.`, - primitiveOverridden: `{{primitive}} is overridden by the {{literal}} in this intersection type.`, + typeOverridden: `{{redundantType}} is overridden by {{nonRedundantType}} in this {{container}} type.`, }, schema: [], }, defaultOptions: [], create(context) { const services = getParserServices(context); - const typesCache = new Map(); - - function getTypeNodeTypePartFlags( - typeNode: TSESTree.TypeNode, - ): TypeFlagsWithName[] { - const keywordTypeFlags = keywordNodeTypesToTsTypes.get(typeNode.type); - if (keywordTypeFlags) { - return [ - { - typeFlags: keywordTypeFlags, - typeName: describeLiteralTypeNode(typeNode), - }, - ]; - } + 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' ? '|' : '&', + ); - 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), - }, - ]; + context.report({ + node: typeNode, + messageId: 'typeOverridden', + data: { + container, + nonRedundantType: nonRedundantTypeName, + redundantType: mergedRedundantTypeName, + }, + }); + } } + } - if (typeNode.type === AST_NODE_TYPES.TSUnionType) { - return typeNode.types.flatMap(getTypeNodeTypePartFlags); + function getUnionTypePart( + typeNode: ts.Node, + checker: ts.TypeChecker, + ): TypeWithName[] { + if (ts.isParenthesizedTypeNode(typeNode)) { + return getUnionTypePart(typeNode.type, checker); } - - const nodeType = services.getTypeAtLocation(typeNode); - const typeParts = unionTypePartsUnlessBoolean(nodeType); - - return typeParts.map(typePart => ({ - typeFlags: typePart.flags, - typeName: describeLiteralType(typePart), - })); + if (ts.isUnionTypeNode(typeNode)) { + return typeNode.types.flatMap(typeNode => + getUnionTypePart(typeNode, checker), + ); + } + const type = checker.getTypeAtLocation(typeNode); + + return [ + { + type, + typeName: checker.typeToString(type), + }, + ]; } - function getTypeNodeTypePartFlagsCached( - typeNode: TSESTree.TypeNode, - ): TypeFlagsWithName[] { - const existing = typesCache.get(typeNode); - if (existing) { - return existing; + function getIntersectionTypePart( + typeNode: ts.Node, + checker: ts.TypeChecker, + ): TypeWithName[] { + if (ts.isParenthesizedTypeNode(typeNode)) { + return getIntersectionTypePart(typeNode.type, checker); } - const created = getTypeNodeTypePartFlags(typeNode); - typesCache.set(typeNode, created); - return created; + if (ts.isIntersectionTypeNode(typeNode)) { + return typeNode.types.flatMap(typeNode => + getIntersectionTypePart(typeNode, checker), + ); + } + + const type = checker.getTypeAtLocation(typeNode); + + return [ + { + type, + typeName: checker.typeToString(type), + }, + ]; } return { - 'TSIntersectionType:exit'(node: TSESTree.TSIntersectionType): void { - const seenLiteralTypes = new Map(); - const seenPrimitiveTypes = new Map< - PrimitiveTypeFlag, - TSESTree.TypeNode[] - >(); - const seenUnionTypes = new Map< + TSIntersectionType(node: TSESTree.TSIntersectionType): void { + const seenTypes = new Set(); + const redundantTypes = new Map< TSESTree.TypeNode, - TypeFlagsWithName[] + TypeRedundancyRelation[] >(); function checkIntersectionBottomAndTopTypes( @@ -310,107 +573,97 @@ export default createRule({ } for (const typeNode of node.types) { - const typePartFlags = getTypeNodeTypePartFlagsCached(typeNode); - - for (const typePart of typePartFlags) { - if (checkIntersectionBottomAndTopTypes(typePart, typeNode)) { + 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, + ); continue; } - - for (const literalTypeFlag of literalTypeFlags) { - if (typePart.typeFlags === literalTypeFlag) { - addToMapGroup( - seenLiteralTypes, - literalToPrimitiveTypeFlags[literalTypeFlag], - typePart.typeName, - ); - break; - } - } - - for (const primitiveTypeFlag of primitiveTypeFlags) { - if (typePart.typeFlags === primitiveTypeFlag) { - addToMapGroup(seenPrimitiveTypes, primitiveTypeFlag, typeNode); - } - } - } - // 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) { + 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 ( - seenPrimitiveTypes.has( - literalToPrimitiveTypeFlags[ - typeFlags as keyof typeof literalToPrimitiveTypeFlags - ], - ) + targetTypeIsRedundant && + targetTypeIsRedundant === sourceTypeIsRedundant ) { - primitive = - literalToPrimitiveTypeFlags[ - typeFlags as keyof typeof literalToPrimitiveTypeFlags - ]; - } else { - primitive = undefined; - break; + continue; + } + if (sourceTypeIsRedundant) { + addToMapGroup(redundantTypes, parentTypeNode, { + nonRedundantTypeWithName: { + type: targetType, + typeName: targetTypeName, + }, + redundantTypeWithName: { + type: sourceType, + typeName: sourceTypeName, + }, + }); + } + if (targetTypeIsRedundant) { + addToMapGroup(redundantTypes, typeNode, { + nonRedundantTypeWithName: { + type: sourceType, + typeName: sourceTypeName, + }, + redundantTypeWithName: { + type: targetType, + typeName: targetTypeName, + }, + }); } - } - 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 - ], - }, - }); } } - }; - 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], - }, - }); + 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; } + + seenTypes.add({ + ...typePart, + parentTypeNode: typeNode, + }); } } + reportRedundantTypes(redundantTypes, 'intersection'); }, - 'TSUnionType:exit'(node: TSESTree.TSUnionType): void { - const seenLiteralTypes = new Map< - PrimitiveTypeFlag, - TypeNodeWithValue[] + TSUnionType(node: TSESTree.TSUnionType): void { + const seenTypes = new Set(); + const redundantTypes = new Map< + TSESTree.TypeNode, + TypeRedundancyRelation[] >(); - const seenPrimitiveTypes = new Set(); function checkUnionBottomAndTopTypes( { typeFlags, typeName }: TypeFlagsWithName, @@ -438,7 +691,7 @@ export default createRule({ if ( typeFlags === ts.TypeFlags.Never && - !isNodeInsideReturnType(node) + !isUnionNodeInsideReturnType(node) ) { context.report({ node: typeNode, @@ -455,79 +708,90 @@ export default createRule({ } for (const typeNode of node.types) { - const typePartFlags = getTypeNodeTypePartFlagsCached(typeNode); - - for (const typePart of typePartFlags) { - if (checkUnionBottomAndTopTypes(typePart, typeNode)) { + 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, + ); continue; } - for (const literalTypeFlag of literalTypeFlags) { - if (typePart.typeFlags === literalTypeFlag) { - addToMapGroup( - seenLiteralTypes, - literalToPrimitiveTypeFlags[literalTypeFlag], - { - literalValue: typePart.typeName, - typeNode, + 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, }, - ); - break; + }); } - } - - for (const primitiveTypeFlag of primitiveTypeFlags) { - if ((typePart.typeFlags & primitiveTypeFlag) !== 0) { - seenPrimitiveTypes.add(primitiveTypeFlag); + if (targetTypeIsRedundant) { + addToMapGroup(redundantTypes, typeNode, { + nonRedundantTypeWithName: { + type: sourceType, + typeName: sourceTypeName, + }, + redundantTypeWithName: { + type: targetType, + typeName: targetTypeName, + }, + }); } } } - } - - 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, - }); + 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; } - } - } - - // 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], - }, + seenTypes.add({ + ...typePart, + parentTypeNode: typeNode, }); } } + + reportRedundantTypes(redundantTypes, 'union'); }, }; }, diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-parameter-property-assignment.ts b/packages/eslint-plugin/src/rules/no-unnecessary-parameter-property-assignment.ts index 3024d4fa0783..9268e07de8b9 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-parameter-property-assignment.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-parameter-property-assignment.ts @@ -109,8 +109,7 @@ export default createRule({ ((node.parameter.type === AST_NODE_TYPES.Identifier && // constructor (public foo) {} node.parameter.name === name) || (node.parameter.type === AST_NODE_TYPES.AssignmentPattern && // constructor (public foo = 1) {} - node.parameter.left.type === AST_NODE_TYPES.Identifier && - node.parameter.left.name === name)) + (node.parameter.left as TSESTree.Identifier).name === name)) ); } diff --git a/packages/eslint-plugin/src/rules/no-unsafe-argument.ts b/packages/eslint-plugin/src/rules/no-unsafe-argument.ts index 4ae7f4bcc28b..d7087988cb30 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[] | TSESTree.Expression[], + args: TSESTree.CallExpressionArgument[], callee: TSESTree.Expression, node: | TSESTree.CallExpression diff --git a/packages/eslint-plugin/src/rules/parameter-properties.ts b/packages/eslint-plugin/src/rules/parameter-properties.ts index fd272b70b1d5..ddc83cd0ac18 100644 --- a/packages/eslint-plugin/src/rules/parameter-properties.ts +++ b/packages/eslint-plugin/src/rules/parameter-properties.ts @@ -107,19 +107,10 @@ export default createRule({ const modifiers = getModifiers(node); if (!allow.includes(modifiers)) { - // HAS to be an identifier or assignment or TSC will throw - if ( - node.parameter.type !== AST_NODE_TYPES.Identifier && - node.parameter.type !== AST_NODE_TYPES.AssignmentPattern - ) { - return; - } - const name = node.parameter.type === AST_NODE_TYPES.Identifier ? node.parameter.name - : // has to be an Identifier or TSC will throw an error - (node.parameter.left as TSESTree.Identifier).name; + : (node.parameter.left as TSESTree.Identifier).name; context.report({ node, 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 89019b1d0a03..1b052ca4a792 100644 --- a/packages/eslint-plugin/src/rules/related-getter-setter-pairs.ts +++ b/packages/eslint-plugin/src/rules/related-getter-setter-pairs.ts @@ -11,9 +11,7 @@ type GetMethod = { returnType: TSESTree.TSTypeAnnotation; } & Method; -type GetMethodRaw = { - returnType: TSESTree.TSTypeAnnotation | undefined; -} & GetMethod; +type GetMethodRaw = GetMethod; type SetMethod = { kind: 'set'; params: [TSESTree.Node] } & Method; diff --git a/packages/eslint-plugin/src/util/class-scope-analyzer/extractComputedName.ts b/packages/eslint-plugin/src/util/class-scope-analyzer/extractComputedName.ts index e100cce75900..ef6b9e1acff2 100644 --- a/packages/eslint-plugin/src/util/class-scope-analyzer/extractComputedName.ts +++ b/packages/eslint-plugin/src/util/class-scope-analyzer/extractComputedName.ts @@ -59,22 +59,11 @@ function extractNonComputedName( */ export function extractNameForMember(node: MemberNode): ExtractedName | null { if (node.type === AST_NODE_TYPES.TSParameterProperty) { - switch (node.parameter.type) { - case AST_NODE_TYPES.ArrayPattern: - case AST_NODE_TYPES.ObjectPattern: - case AST_NODE_TYPES.RestElement: - // Nonsensical properties -- see https://github.com/typescript-eslint/typescript-eslint/issues/11708 - return null; - - case AST_NODE_TYPES.AssignmentPattern: - if (node.parameter.left.type !== AST_NODE_TYPES.Identifier) { - return null; - } - return extractNonComputedName(node.parameter.left); - - case AST_NODE_TYPES.Identifier: - return extractNonComputedName(node.parameter); - } + const identifier = + node.parameter.type === AST_NODE_TYPES.Identifier + ? node.parameter + : (node.parameter.left as TSESTree.Identifier); + return extractNonComputedName(identifier); } if (node.computed) { diff --git a/packages/eslint-plugin/src/util/collectUnusedVariables.ts b/packages/eslint-plugin/src/util/collectUnusedVariables.ts index c98529f68a63..d4d04fefb960 100644 --- a/packages/eslint-plugin/src/util/collectUnusedVariables.ts +++ b/packages/eslint-plugin/src/util/collectUnusedVariables.ts @@ -141,12 +141,10 @@ class UnusedVarsVisitor extends Visitor { } protected TSParameterProperty(node: TSESTree.TSParameterProperty): void { - let identifier: TSESTree.Identifier | null = null; + let identifier: TSESTree.Identifier; switch (node.parameter.type) { case AST_NODE_TYPES.AssignmentPattern: - if (node.parameter.left.type === AST_NODE_TYPES.Identifier) { - identifier = node.parameter.left; - } + identifier = node.parameter.left as TSESTree.Identifier; break; case AST_NODE_TYPES.Identifier: @@ -154,9 +152,7 @@ class UnusedVarsVisitor extends Visitor { break; } - if (identifier) { - this.markVariableAsUsed(identifier); - } + this.markVariableAsUsed(identifier); } private collectUnusedVariables( 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 f6fb194487d8..c194fd0da174 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 the false in this intersection type. + ~~~~~~~ boolean is overridden by false in this intersection type. type IntersectionNumberLiteral = number & 1; - ~~~~~~ number is overridden by the 1 in this intersection type. + ~~~~~~ number is overridden by 1 in this intersection type. type IntersectionStringLiteral = string & 'foo'; - ~~~~~~ string is overridden by the "foo" in this intersection type. + ~~~~~~ string is overridden by "foo" in this intersection type. Correct diff --git a/packages/eslint-plugin/tests/rules/consistent-generic-constructors.test.ts b/packages/eslint-plugin/tests/rules/consistent-generic-constructors.test.ts index 1a573186b1ae..f9a49b470805 100644 --- a/packages/eslint-plugin/tests/rules/consistent-generic-constructors.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-generic-constructors.test.ts @@ -44,6 +44,38 @@ class A { `, ` const a = function (a: Foo = new Foo()) {}; + `, + ` +const a: Float32Array = new Float32Array(); +export {}; + `, + ` +const a: Float64Array = new Float64Array(); +export {}; + `, + ` +const a: Int16Array = new Int16Array(); +export {}; + `, + ` +const a: Int8Array = new Int8Array(); +export {}; + `, + ` +const a: Uint16Array = new Uint16Array(); +export {}; + `, + ` +const a: Uint32Array = new Uint32Array(); +export {}; + `, + ` +const a: Uint8Array = new Uint8Array(); +export {}; + `, + ` +const a: Uint8ClampedArray = new Uint8ClampedArray(); +export {}; `, { code: ` @@ -592,5 +624,22 @@ const a = function (a = new Foo()) {}; const a = function (a: Foo = new Foo()) {}; `, }, + { + code: ` +class Float32Array {} +const a: Float32Array = new Float32Array(); +export {}; + `, + errors: [ + { + messageId: 'preferConstructor', + }, + ], + output: ` +class Float32Array {} +const a = new Float32Array(); +export {}; + `, + }, ], }); diff --git a/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts b/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts index 6aa2bf795749..eb3eed19b2f5 100644 --- a/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts +++ b/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts @@ -302,14 +302,6 @@ class Test { }, { code: ` -class Test { - constructor(private { x }: any[]) {} -} - `, - options: [{ accessibility: 'no-public' }], - }, - { - code: ` class Test { #foo = 1; #bar() {} diff --git a/packages/eslint-plugin/tests/rules/explicit-module-boundary-types.test.ts b/packages/eslint-plugin/tests/rules/explicit-module-boundary-types.test.ts index 1897957aa5e3..1edde49701c2 100644 --- a/packages/eslint-plugin/tests/rules/explicit-module-boundary-types.test.ts +++ b/packages/eslint-plugin/tests/rules/explicit-module-boundary-types.test.ts @@ -1382,27 +1382,16 @@ export class Test { { code: ` export class Test { - constructor( - public foo, - private ...bar, - ) {} + constructor(public foo) {} } `, errors: [ { - column: 12, + column: 22, data: { name: 'foo', }, - line: 4, - messageId: 'missingArgType', - }, - { - column: 5, - data: { - name: 'bar', - }, - line: 5, + line: 3, messageId: 'missingArgType', }, ], 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 ce51eb308044..8b6ff31b62c9 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,8 +156,132 @@ 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;', @@ -320,10 +444,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 19, data: { - literal: '0', - primitive: 'number', + container: 'union', + nonRedundantType: 'number', + redundantType: '0', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -333,10 +458,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 20, data: { - literal: '0 | 1', - primitive: 'number', + container: 'union', + nonRedundantType: 'number', + redundantType: '0 | 1', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -346,10 +472,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 11, data: { - literal: '0 | 0', - primitive: 'number', + container: 'union', + nonRedundantType: 'number', + redundantType: '0 | 0', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -362,10 +489,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 19, data: { - literal: '2 | 0 | 1', - primitive: 'number', + container: 'union', + nonRedundantType: 'number', + redundantType: '2 | B', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -375,10 +503,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 11, data: { - literal: '0 | 1 | 2', - primitive: 'number', + container: 'union', + nonRedundantType: 'number', + redundantType: '0 | 1 | 2', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -388,10 +517,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 11, data: { - literal: '0 | 1', - primitive: 'number', + container: 'union', + nonRedundantType: 'number', + redundantType: '0 | 1', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -401,10 +531,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 11, data: { - literal: '0 | 0 | 1', - primitive: 'number', + container: 'union', + nonRedundantType: 'number', + redundantType: '0 | 0 | 1', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -414,10 +545,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 11, data: { - literal: '2 | 3', - primitive: 'number', + container: 'union', + nonRedundantType: 'number', + redundantType: '2 | 3', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -427,10 +559,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 10, data: { - literal: '""', - primitive: 'string', + container: 'union', + nonRedundantType: 'string', + redundantType: '""', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -443,10 +576,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 18, data: { - literal: '"b"', - primitive: 'string', + container: 'union', + nonRedundantType: 'string', + redundantType: '"b"', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -456,10 +590,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 10, data: { - literal: 'template literal type', - primitive: 'string', + container: 'union', + nonRedundantType: 'string', + redundantType: '`a${number}c`', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -472,10 +607,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 18, data: { - literal: 'template literal type', - primitive: 'string', + container: 'union', + nonRedundantType: 'string', + redundantType: '`a${number}c`', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -485,10 +621,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 10, data: { - literal: 'template literal type', - primitive: 'string', + container: 'union', + nonRedundantType: 'string', + redundantType: '`${number}`', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -498,10 +635,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 10, data: { - literal: '0n', - primitive: 'bigint', + container: 'union', + nonRedundantType: 'bigint', + redundantType: '0n', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -511,10 +649,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 10, data: { - literal: '-1n', - primitive: 'bigint', + container: 'union', + nonRedundantType: 'bigint', + redundantType: '-1n', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -524,10 +663,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 11, data: { - literal: '-1n | 1n', - primitive: 'bigint', + container: 'union', + nonRedundantType: 'bigint', + redundantType: '-1n | 1n', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -540,10 +680,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 22, data: { - literal: 'false', - primitive: 'boolean', + container: 'union', + nonRedundantType: 'boolean', + redundantType: 'false', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -553,10 +694,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 10, data: { - literal: 'false', - primitive: 'boolean', + container: 'union', + nonRedundantType: 'boolean', + redundantType: 'false', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -566,10 +708,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 10, data: { - literal: 'true', - primitive: 'boolean', + container: 'union', + nonRedundantType: 'boolean', + redundantType: 'true', }, - messageId: 'literalOverridden', + messageId: 'typeOverridden', }, ], }, @@ -579,10 +722,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 18, data: { - literal: 'false', - primitive: 'boolean', + container: 'intersection', + nonRedundantType: 'false', + redundantType: 'boolean', }, - messageId: 'primitiveOverridden', + messageId: 'typeOverridden', }, ], }, @@ -595,10 +739,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 22, data: { - literal: 'false', - primitive: 'boolean', + container: 'intersection', + nonRedundantType: 'false', + redundantType: 'boolean', }, - messageId: 'primitiveOverridden', + messageId: 'typeOverridden', }, ], }, @@ -611,10 +756,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 22, data: { - literal: 'true', - primitive: 'boolean', + container: 'intersection', + nonRedundantType: 'true', + redundantType: 'boolean', }, - messageId: 'primitiveOverridden', + messageId: 'typeOverridden', }, ], }, @@ -624,10 +770,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 17, data: { - literal: 'true', - primitive: 'boolean', + container: 'intersection', + nonRedundantType: 'true', + redundantType: 'boolean', }, - messageId: 'primitiveOverridden', + messageId: 'typeOverridden', }, ], }, @@ -744,10 +891,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 10, data: { - literal: '0', - primitive: 'number', + container: 'intersection', + nonRedundantType: '0', + redundantType: 'number', }, - messageId: 'primitiveOverridden', + messageId: 'typeOverridden', }, ], }, @@ -757,10 +905,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 15, data: { - literal: '""', - primitive: 'string', + container: 'intersection', + nonRedundantType: '""', + redundantType: 'string', }, - messageId: 'primitiveOverridden', + messageId: 'typeOverridden', }, ], }, @@ -773,10 +922,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 22, data: { - literal: '0n', - primitive: 'bigint', + container: 'intersection', + nonRedundantType: '0n', + redundantType: 'bigint', }, - messageId: 'primitiveOverridden', + messageId: 'typeOverridden', }, ], }, @@ -786,10 +936,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 15, data: { - literal: '0n', - primitive: 'bigint', + container: 'intersection', + nonRedundantType: '0n', + redundantType: 'bigint', }, - messageId: 'primitiveOverridden', + messageId: 'typeOverridden', }, ], }, @@ -799,10 +950,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { { column: 16, data: { - literal: '-1n', - primitive: 'bigint', + container: 'intersection', + nonRedundantType: '-1n', + redundantType: 'bigint', }, - messageId: 'primitiveOverridden', + messageId: 'typeOverridden', }, ], }, @@ -813,12 +965,13 @@ ruleTester.run('no-redundant-type-constituents', rule, { `, errors: [ { - column: 18, + column: 22, data: { - literal: '"a" | "b"', - primitive: 'string', + container: 'intersection', + nonRedundantType: 'T', + redundantType: 'string', }, - messageId: 'primitiveOverridden', + messageId: 'typeOverridden', }, ], }, @@ -828,22 +981,1320 @@ 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: { - literal: '1 | 2', - primitive: 'number', + container: 'union', + typeName: 'any', + }, + messageId: 'overrides', + }, + ], + }, + { + code: 'type T = { a: 1 } | never;', + errors: [ + { + column: 21, + data: { + container: 'union', + typeName: 'never', }, - messageId: 'primitiveOverridden', + messageId: 'overridden', }, + ], + }, + { + code: ` + type B = { a: 1 }; + type T = B | never; + `, + errors: [ { column: 22, data: { - literal: '"a" | "b"', - primitive: 'string', + 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; }]', }, - messageId: 'primitiveOverridden', + endColumn: 25, + messageId: 'typeOverridden', }, ], }, diff --git a/packages/eslint-plugin/tests/rules/parameter-properties.test.ts b/packages/eslint-plugin/tests/rules/parameter-properties.test.ts index 36a14677339e..53d2177e174c 100644 --- a/packages/eslint-plugin/tests/rules/parameter-properties.test.ts +++ b/packages/eslint-plugin/tests/rules/parameter-properties.test.ts @@ -113,18 +113,6 @@ class Foo { `, options: [{ allow: ['public readonly', 'private'] }], }, - // Semantically invalid test case - ` -class Foo { - constructor(private ...name: string[]) {} -} - `, - // Semantically invalid test case - ` -class Foo { - constructor(private [test]: [string]) {} -} - `, { code: ` class Foo { diff --git a/packages/eslint-plugin/tsconfig.json b/packages/eslint-plugin/tsconfig.json index 57673ed7cbf0..7cca541fe1a1 100644 --- a/packages/eslint-plugin/tsconfig.json +++ b/packages/eslint-plugin/tsconfig.json @@ -3,27 +3,6 @@ "files": [], "include": [], "references": [ - { - "path": "../visitor-keys" - }, - { - "path": "../type-utils" - }, - { - "path": "../scope-manager" - }, - { - "path": "../rule-tester" - }, - { - "path": "../rule-schema-to-typescript-types" - }, - { - "path": "../parser" - }, - { - "path": "../utils" - }, { "path": "./tsconfig.build.json" }, diff --git a/packages/parser/CHANGELOG.md b/packages/parser/CHANGELOG.md index 4c49a7633558..9d50518c76c1 100644 --- a/packages/parser/CHANGELOG.md +++ b/packages/parser/CHANGELOG.md @@ -1,3 +1,9 @@ +## 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. + +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.47.0 (2025-11-17) 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 53ec1a75869d..d17ee0e04382 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/parser", - "version": "8.47.0", + "version": "8.48.0", "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.47.0", - "@typescript-eslint/types": "8.47.0", - "@typescript-eslint/typescript-estree": "8.47.0", - "@typescript-eslint/visitor-keys": "8.47.0", + "@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", "debug": "^4.3.4" }, "devDependencies": { diff --git a/packages/parser/tsconfig.json b/packages/parser/tsconfig.json index 8122a5aaab8a..d4d0929e1955 100644 --- a/packages/parser/tsconfig.json +++ b/packages/parser/tsconfig.json @@ -3,18 +3,6 @@ "files": [], "include": [], "references": [ - { - "path": "../visitor-keys" - }, - { - "path": "../typescript-estree" - }, - { - "path": "../types" - }, - { - "path": "../scope-manager" - }, { "path": "./tsconfig.build.json" }, diff --git a/packages/project-service/CHANGELOG.md b/packages/project-service/CHANGELOG.md index 3066789d747d..e15ae53bb3ba 100644 --- a/packages/project-service/CHANGELOG.md +++ b/packages/project-service/CHANGELOG.md @@ -1,3 +1,9 @@ +## 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. + +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.47.0 (2025-11-17) 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 3cf0f0a9ccc5..c4893bfb50ae 100644 --- a/packages/project-service/package.json +++ b/packages/project-service/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/project-service", - "version": "8.47.0", + "version": "8.48.0", "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.47.0", - "@typescript-eslint/types": "^8.47.0", + "@typescript-eslint/tsconfig-utils": "^8.48.0", + "@typescript-eslint/types": "^8.48.0", "debug": "^4.3.4" }, "devDependencies": { diff --git a/packages/project-service/tsconfig.json b/packages/project-service/tsconfig.json index 8029bc0ac19d..d4d0929e1955 100644 --- a/packages/project-service/tsconfig.json +++ b/packages/project-service/tsconfig.json @@ -3,12 +3,6 @@ "files": [], "include": [], "references": [ - { - "path": "../tsconfig-utils" - }, - { - "path": "../types" - }, { "path": "./tsconfig.build.json" }, diff --git a/packages/rule-schema-to-typescript-types/CHANGELOG.md b/packages/rule-schema-to-typescript-types/CHANGELOG.md index fdb759518e94..1f13e1293745 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.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. + +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.47.0 (2025-11-17) 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 c2671e0ef36e..f8983bc4acd6 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.47.0", + "version": "8.48.0", "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.47.0", - "@typescript-eslint/utils": "8.47.0", + "@typescript-eslint/type-utils": "8.48.0", + "@typescript-eslint/utils": "8.48.0", "natural-compare": "^1.4.0" }, "devDependencies": { diff --git a/packages/rule-schema-to-typescript-types/tsconfig.json b/packages/rule-schema-to-typescript-types/tsconfig.json index f1e1288b8561..d4d0929e1955 100644 --- a/packages/rule-schema-to-typescript-types/tsconfig.json +++ b/packages/rule-schema-to-typescript-types/tsconfig.json @@ -3,12 +3,6 @@ "files": [], "include": [], "references": [ - { - "path": "../utils" - }, - { - "path": "../type-utils" - }, { "path": "./tsconfig.build.json" }, diff --git a/packages/rule-tester/CHANGELOG.md b/packages/rule-tester/CHANGELOG.md index 5efc9041311a..0c170ccef9ce 100644 --- a/packages/rule-tester/CHANGELOG.md +++ b/packages/rule-tester/CHANGELOG.md @@ -1,3 +1,15 @@ +## 8.48.0 (2025-11-24) + +### 🚀 Features + +- **rule-tester:** remove workaround for jest circular structure error ([#11772](https://github.com/typescript-eslint/typescript-eslint/pull/11772)) + +### ❤️ Thank You + +- Kirk Waiblinger @kirkwaiblinger + +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.47.0 (2025-11-17) This was a version bump only for rule-tester to align it with other projects, there were no code changes. diff --git a/packages/rule-tester/package.json b/packages/rule-tester/package.json index cf69ec3e88cd..aa71d1a8079f 100644 --- a/packages/rule-tester/package.json +++ b/packages/rule-tester/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/rule-tester", - "version": "8.47.0", + "version": "8.48.0", "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.47.0", - "@typescript-eslint/typescript-estree": "8.47.0", - "@typescript-eslint/utils": "8.47.0", + "@typescript-eslint/parser": "8.48.0", + "@typescript-eslint/typescript-estree": "8.48.0", + "@typescript-eslint/utils": "8.48.0", "ajv": "^6.12.6", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "4.6.2", diff --git a/packages/rule-tester/src/RuleTester.ts b/packages/rule-tester/src/RuleTester.ts index 723bc6b17227..dfac9486ddb0 100644 --- a/packages/rule-tester/src/RuleTester.ts +++ b/packages/rule-tester/src/RuleTester.ts @@ -219,31 +219,11 @@ export class RuleTester extends TestFramework { let linterForBasePath = this.#lintersByBasePath.get(basePath); if (!linterForBasePath) { - linterForBasePath = (() => { - const linter = new Linter({ - configType: 'flat', - cwd: basePath, - }); - - // This nonsense is a workaround for https://github.com/jestjs/jest/issues/14840 - // see also https://github.com/typescript-eslint/typescript-eslint/issues/8942 - // - // For some reason rethrowing exceptions skirts around the circular JSON error. - const oldVerify = linter.verify.bind(linter); - linter.verify = ( - ...args: Parameters - ): ReturnType => { - try { - return oldVerify(...args); - } catch (error) { - throw new Error('Caught an error while linting', { - cause: error, - }); - } - }; + linterForBasePath = new Linter({ + configType: 'flat', + cwd: basePath, + }); - return linter; - })(); this.#lintersByBasePath.set(basePath, linterForBasePath); } return linterForBasePath; diff --git a/packages/rule-tester/tsconfig.json b/packages/rule-tester/tsconfig.json index 2eb8e60114d8..d4d0929e1955 100644 --- a/packages/rule-tester/tsconfig.json +++ b/packages/rule-tester/tsconfig.json @@ -3,15 +3,6 @@ "files": [], "include": [], "references": [ - { - "path": "../utils" - }, - { - "path": "../typescript-estree" - }, - { - "path": "../parser" - }, { "path": "./tsconfig.build.json" }, diff --git a/packages/scope-manager/CHANGELOG.md b/packages/scope-manager/CHANGELOG.md index 1d83ee47c4fd..0a5b2c19ff9d 100644 --- a/packages/scope-manager/CHANGELOG.md +++ b/packages/scope-manager/CHANGELOG.md @@ -1,3 +1,21 @@ +## 8.48.0 (2025-11-24) + +### 🚀 Features + +- **eslint-plugin:** [no-redundant-type-constituents] use assignability checking for redundancy checks ([#10744](https://github.com/typescript-eslint/typescript-eslint/pull/10744)) + +### 🩹 Fixes + +- **scope-manager:** change unhelpful `aaa` error message and change `analyze` to expects `Program` ([#11747](https://github.com/typescript-eslint/typescript-eslint/pull/11747)) + +### ❤️ Thank You + +- Josh Goldberg +- mdm317 @gen-ip-1 +- Younsang Na @nayounsang + +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.47.0 (2025-11-17) This was a version bump only for scope-manager to align it with other projects, there were no code changes. diff --git a/packages/scope-manager/package.json b/packages/scope-manager/package.json index 4f0304095919..770c3ca3d26e 100644 --- a/packages/scope-manager/package.json +++ b/packages/scope-manager/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/scope-manager", - "version": "8.47.0", + "version": "8.48.0", "description": "TypeScript scope analyser for ESLint", "files": [ "dist", @@ -47,11 +47,11 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/types": "8.47.0", - "@typescript-eslint/visitor-keys": "8.47.0" + "@typescript-eslint/types": "8.48.0", + "@typescript-eslint/visitor-keys": "8.48.0" }, "devDependencies": { - "@typescript-eslint/typescript-estree": "8.47.0", + "@typescript-eslint/typescript-estree": "8.48.0", "@vitest/coverage-v8": "^3.1.3", "@vitest/pretty-format": "^3.1.3", "eslint": "*", diff --git a/packages/scope-manager/src/analyze.ts b/packages/scope-manager/src/analyze.ts index a35031ca0b7a..a050a723c42e 100644 --- a/packages/scope-manager/src/analyze.ts +++ b/packages/scope-manager/src/analyze.ts @@ -81,7 +81,7 @@ const DEFAULT_OPTIONS: Required = { * Takes an AST and returns the analyzed scopes. */ export function analyze( - tree: TSESTree.Node, + tree: TSESTree.Program, providedOptions?: AnalyzeOptions, ): ScopeManager { const options: Required = { diff --git a/packages/scope-manager/src/referencer/Referencer.ts b/packages/scope-manager/src/referencer/Referencer.ts index 562921170751..1777491588ae 100644 --- a/packages/scope-manager/src/referencer/Referencer.ts +++ b/packages/scope-manager/src/referencer/Referencer.ts @@ -93,7 +93,10 @@ export class Referencer extends Visitor { public currentScope(throwOnNull: true): Scope | null; public currentScope(dontThrowOnNull?: true): Scope | null { if (!dontThrowOnNull) { - assert(this.scopeManager.currentScope, 'aaa'); + assert( + this.scopeManager.currentScope, + 'Expected currentScope to exist. This usually happens when analyze() is called with an incomplete AST node instead of a complete Program node.', + ); } return this.scopeManager.currentScope; } diff --git a/packages/scope-manager/tests/analyze.test.ts b/packages/scope-manager/tests/analyze.test.ts new file mode 100644 index 000000000000..f100b9fddd40 --- /dev/null +++ b/packages/scope-manager/tests/analyze.test.ts @@ -0,0 +1,16 @@ +import { analyze } from '../src'; +import { parse } from './test-utils'; + +describe('analyze()', () => { + it('should throw error when passed a partial AST node', () => { + const ast = parse(`const hello: string = 'world';`, { + range: true, + }); + const partialNode = ast.body[0]; + + expect(() => { + // @ts-expect-error -- to reproduce https://github.com/typescript-eslint/typescript-eslint/issues/11727 + analyze(partialNode); + }).toThrow(); + }); +}); diff --git a/packages/scope-manager/tests/test-utils/serializers/TSESTreeNode.ts b/packages/scope-manager/tests/test-utils/serializers/TSESTreeNode.ts index 733deaa0257d..cad4cb206d25 100644 --- a/packages/scope-manager/tests/test-utils/serializers/TSESTreeNode.ts +++ b/packages/scope-manager/tests/test-utils/serializers/TSESTreeNode.ts @@ -17,7 +17,10 @@ const EXCLUDED_KEYS = new Set([ const generator = createIdGenerator(); type Node = { type: AST_NODE_TYPES } & Record; -type Identifier = { name: string; type: AST_NODE_TYPES.Identifier } & Node; +type Identifier = { name: string; type: AST_NODE_TYPES.Identifier } & Record< + string, + unknown +>; const SEEN_NODES = new Map(); export const serializer: NewPlugin = { diff --git a/packages/scope-manager/tsconfig.json b/packages/scope-manager/tsconfig.json index 44cfc868c8d6..d4d0929e1955 100644 --- a/packages/scope-manager/tsconfig.json +++ b/packages/scope-manager/tsconfig.json @@ -3,15 +3,6 @@ "files": [], "include": [], "references": [ - { - "path": "../visitor-keys" - }, - { - "path": "../types" - }, - { - "path": "../typescript-estree" - }, { "path": "./tsconfig.build.json" }, diff --git a/packages/tsconfig-utils/CHANGELOG.md b/packages/tsconfig-utils/CHANGELOG.md index a2a36907cb3f..a53cf9e3a787 100644 --- a/packages/tsconfig-utils/CHANGELOG.md +++ b/packages/tsconfig-utils/CHANGELOG.md @@ -1,3 +1,9 @@ +## 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. + +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.47.0 (2025-11-17) 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 a4274d681783..35b4112f3996 100644 --- a/packages/tsconfig-utils/package.json +++ b/packages/tsconfig-utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/tsconfig-utils", - "version": "8.47.0", + "version": "8.48.0", "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 2eec584f475b..5366d94fdd5e 100644 --- a/packages/type-utils/CHANGELOG.md +++ b/packages/type-utils/CHANGELOG.md @@ -1,3 +1,9 @@ +## 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. + +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.47.0 (2025-11-17) 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 632d9478fd1d..9a637841326d 100644 --- a/packages/type-utils/package.json +++ b/packages/type-utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/type-utils", - "version": "8.47.0", + "version": "8.48.0", "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.47.0", - "@typescript-eslint/typescript-estree": "8.47.0", - "@typescript-eslint/utils": "8.47.0", + "@typescript-eslint/types": "8.48.0", + "@typescript-eslint/typescript-estree": "8.48.0", + "@typescript-eslint/utils": "8.48.0", "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.47.0", + "@typescript-eslint/parser": "8.48.0", "@vitest/coverage-v8": "^3.1.3", "ajv": "^6.12.6", "eslint": "*", diff --git a/packages/type-utils/tsconfig.json b/packages/type-utils/tsconfig.json index a57d8d1814a8..d4d0929e1955 100644 --- a/packages/type-utils/tsconfig.json +++ b/packages/type-utils/tsconfig.json @@ -3,18 +3,6 @@ "files": [], "include": [], "references": [ - { - "path": "../types" - }, - { - "path": "../utils" - }, - { - "path": "../typescript-estree" - }, - { - "path": "../parser" - }, { "path": "./tsconfig.build.json" }, diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index 167cc6c8c1bc..f62cf2bf1348 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -1,3 +1,9 @@ +## 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. + +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.47.0 (2025-11-17) 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 8b103568746c..6c2fe5c6ff09 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/types", - "version": "8.47.0", + "version": "8.48.0", "description": "Types for the TypeScript-ESTree AST spec", "files": [ "dist", @@ -60,6 +60,9 @@ }, "nx": { "name": "types", + "implicitDependencies": [ + "ast-spec" + ], "includedScripts": [ "clean" ], diff --git a/packages/types/tools/copy-ast-spec.mts b/packages/types/tools/copy-ast-spec.mts index 110a92854422..8f7b82f17aaa 100644 --- a/packages/types/tools/copy-ast-spec.mts +++ b/packages/types/tools/copy-ast-spec.mts @@ -72,11 +72,6 @@ async function copyFile( console.log('Copied', fileName); } -if (process.env.SKIP_AST_SPEC_REBUILD) { - // ensure the package is built - await execAsync('yarn', ['build'], { cwd: AST_SPEC_PATH }); -} - await copyFile('dist', 'ast-spec.ts', code => code.replaceAll('export declare enum', 'export enum'), ); diff --git a/packages/typescript-eslint/CHANGELOG.md b/packages/typescript-eslint/CHANGELOG.md index 3e4bd06180c6..06dfa57847c5 100644 --- a/packages/typescript-eslint/CHANGELOG.md +++ b/packages/typescript-eslint/CHANGELOG.md @@ -1,3 +1,9 @@ +## 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. + +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.47.0 (2025-11-17) 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 9334a320109c..db25dcd8ce12 100644 --- a/packages/typescript-eslint/package.json +++ b/packages/typescript-eslint/package.json @@ -1,6 +1,6 @@ { "name": "typescript-eslint", - "version": "8.47.0", + "version": "8.48.0", "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.47.0", - "@typescript-eslint/parser": "8.47.0", - "@typescript-eslint/typescript-estree": "8.47.0", - "@typescript-eslint/utils": "8.47.0" + "@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" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", diff --git a/packages/typescript-eslint/tsconfig.json b/packages/typescript-eslint/tsconfig.json index f94f467e0b00..d4d0929e1955 100644 --- a/packages/typescript-eslint/tsconfig.json +++ b/packages/typescript-eslint/tsconfig.json @@ -3,18 +3,6 @@ "files": [], "include": [], "references": [ - { - "path": "../typescript-estree" - }, - { - "path": "../utils" - }, - { - "path": "../parser" - }, - { - "path": "../eslint-plugin" - }, { "path": "./tsconfig.build.json" }, diff --git a/packages/typescript-estree/CHANGELOG.md b/packages/typescript-estree/CHANGELOG.md index 5544bf977778..52542a23c60d 100644 --- a/packages/typescript-estree/CHANGELOG.md +++ b/packages/typescript-estree/CHANGELOG.md @@ -1,3 +1,30 @@ +## 8.48.0 (2025-11-24) + +### 🚀 Features + +- **typescript-estree:** replace fast-glob with tinyglobby ([#11740](https://github.com/typescript-eslint/typescript-eslint/pull/11740)) +- **eslint-plugin:** [no-redundant-type-constituents] use assignability checking for redundancy checks ([#10744](https://github.com/typescript-eslint/typescript-eslint/pull/10744)) +- **typescript-estree:** gate all errors behind allowInvalidAST ([#11693](https://github.com/typescript-eslint/typescript-eslint/pull/11693)) + +### 🩹 Fixes + +- **typescript-estree:** disallow binding patterns in parameter properties ([#11760](https://github.com/typescript-eslint/typescript-eslint/pull/11760)) +- **typescript-estree:** infers singleRun as true for project service ([#11327](https://github.com/typescript-eslint/typescript-eslint/pull/11327)) + +### ❤️ Thank You + +- Ben McCann @benmccann +- Dima Barabash @dbarabashh +- fisker Cheung @fisker +- James Henry @JamesHenry +- JamesHenry @JamesHenry +- Josh Goldberg +- Josh Goldberg ✨ +- mdm317 @gen-ip-1 +- Younsang Na @nayounsang + +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.47.0 (2025-11-17) This was a version bump only for typescript-estree to align it with other projects, there were no code changes. diff --git a/packages/typescript-estree/package.json b/packages/typescript-estree/package.json index e7bd58960daf..db887a19bea6 100644 --- a/packages/typescript-estree/package.json +++ b/packages/typescript-estree/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/typescript-estree", - "version": "8.47.0", + "version": "8.48.0", "description": "A parser that converts TypeScript source code into an ESTree compatible form", "files": [ "dist", @@ -52,19 +52,17 @@ "typecheck": "yarn run -BT nx typecheck" }, "dependencies": { - "@typescript-eslint/project-service": "8.47.0", - "@typescript-eslint/tsconfig-utils": "8.47.0", - "@typescript-eslint/types": "8.47.0", - "@typescript-eslint/visitor-keys": "8.47.0", + "@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", "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", + "tinyglobby": "^0.2.15", "ts-api-utils": "^2.1.0" }, "devDependencies": { - "@types/is-glob": "^4.0.4", "@vitest/coverage-v8": "^3.1.3", "eslint": "*", "glob": "*", diff --git a/packages/typescript-estree/src/check-modifiers.ts b/packages/typescript-estree/src/check-modifiers.ts index 423604a70e01..1a979338dceb 100644 --- a/packages/typescript-estree/src/check-modifiers.ts +++ b/packages/typescript-estree/src/check-modifiers.ts @@ -370,6 +370,24 @@ export function checkModifiers(node: ts.Node): void { 'A parameter property is only allowed in a constructor implementation.', ); } + const param = node as ts.ParameterDeclaration; + + if (param.dotDotDotToken) { + throwError( + modifier, + 'A parameter property cannot be a rest parameter.', + ); + } + + if ( + param.name.kind === SyntaxKind.ArrayBindingPattern || + param.name.kind === SyntaxKind.ObjectBindingPattern + ) { + throwError( + modifier, + 'A parameter property may not be declared using a binding pattern.', + ); + } } // There are more cases in `checkGrammarObjectLiteralExpression` in TypeScript. diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 3facbe34af20..1825bc4d6a37 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -159,7 +159,13 @@ export class Converter { checkModifiers(node); } - #throwError(node: number | ts.Node | TSESTree.Range, message: string): never { + #throwError( + node: number | ts.Node | TSESTree.Range, + message: string, + ): asserts node is never { + if (this.options.allowInvalidAST) { + return; + } let start; let end; if (Array.isArray(node)) { @@ -174,15 +180,6 @@ export class Converter { throw createError(message, this.ast, start, end); } - #throwUnlessAllowInvalidAST( - node: number | ts.Node | TSESTree.Range, - message: string, - ): asserts node is never { - if (!this.options.allowInvalidAST) { - this.#throwError(node, message); - } - } - /** * Creates a getter for a property under aliasKey that returns the value under * valueKey. If suppressDeprecatedPropertyWarnings is not enabled, the @@ -276,17 +273,14 @@ export class Converter { allowNull: boolean, ): void { if (!allowNull && node.moduleSpecifier == null) { - this.#throwUnlessAllowInvalidAST( - node, - 'Module specifier must be a string literal.', - ); + this.#throwError(node, 'Module specifier must be a string literal.'); } if ( node.moduleSpecifier && node.moduleSpecifier?.kind !== SyntaxKind.StringLiteral ) { - this.#throwUnlessAllowInvalidAST( + this.#throwError( node.moduleSpecifier, 'Module specifier must be a string literal.', ); @@ -848,10 +842,7 @@ export class Converter { case SyntaxKind.ThrowStatement: if (node.expression.end === node.expression.pos) { - this.#throwUnlessAllowInvalidAST( - node, - 'A throw statement must throw an expression.', - ); + this.#throwError(node, 'A throw statement must throw an expression.'); } return this.createNode(node, { @@ -1033,7 +1024,7 @@ export class Converter { }); if (!result.declarations.length) { - this.#throwUnlessAllowInvalidAST( + this.#throwError( node, 'A variable declaration list must have at least one variable declarator.', ); @@ -1179,7 +1170,7 @@ export class Converter { property.kind === SyntaxKind.MethodDeclaration) && !property.body ) { - this.#throwUnlessAllowInvalidAST(property.end - 1, "'{' expected."); + this.#throwError(property.end - 1, "'{' expected."); } properties.push(this.convertChild(property) as TSESTree.Property); @@ -1832,7 +1823,7 @@ export class Converter { accessibility: getTSNodeAccessibility(node), decorators: [], override: hasModifier(SyntaxKind.OverrideKeyword, node), - parameter: result, + parameter: result as TSESTree.TSParameterProperty['parameter'], readonly: hasModifier(SyntaxKind.ReadonlyKeyword, node), static: hasModifier(SyntaxKind.StaticKeyword, node), }); @@ -1848,7 +1839,7 @@ export class Converter { (!hasModifier(ts.SyntaxKind.ExportKeyword, node) || !hasModifier(ts.SyntaxKind.DefaultKeyword, node)) ) { - this.#throwUnlessAllowInvalidAST( + this.#throwError( node, "A class declaration without the 'default' modifier must have a name.", ); @@ -1867,7 +1858,7 @@ export class Converter { const { token, types } = heritageClause; if (types.length === 0) { - this.#throwUnlessAllowInvalidAST( + this.#throwError( heritageClause, `'${ts.tokenToString(token)}' list cannot be empty.`, ); @@ -1875,21 +1866,21 @@ export class Converter { if (token === SyntaxKind.ExtendsKeyword) { if (extendsClause) { - this.#throwUnlessAllowInvalidAST( + this.#throwError( heritageClause, "'extends' clause already seen.", ); } if (implementsClause) { - this.#throwUnlessAllowInvalidAST( + this.#throwError( heritageClause, "'extends' clause must precede 'implements' clause.", ); } if (types.length > 1) { - this.#throwUnlessAllowInvalidAST( + this.#throwError( types[1], 'Classes can only extend a single class.', ); @@ -1898,7 +1889,7 @@ export class Converter { extendsClause ??= heritageClause; } else if (token === SyntaxKind.ImplementsKeyword) { if (implementsClause) { - this.#throwUnlessAllowInvalidAST( + this.#throwError( heritageClause, "'implements' clause already seen.", ); @@ -2118,7 +2109,7 @@ export class Converter { */ if (operator === '++' || operator === '--') { if (!isValidAssignmentTarget(node.operand)) { - this.#throwUnlessAllowInvalidAST( + this.#throwError( node.operand, 'Invalid left-hand side expression in unary operation', ); @@ -2273,7 +2264,7 @@ export class Converter { case SyntaxKind.CallExpression: { if (node.expression.kind === SyntaxKind.ImportKeyword) { if (node.arguments.length !== 1 && node.arguments.length !== 2) { - this.#throwUnlessAllowInvalidAST( + this.#throwError( node.arguments[2] ?? node, 'Dynamic import requires exactly one or two arguments.', ); @@ -2691,7 +2682,7 @@ export class Converter { case SyntaxKind.MappedType: { if (node.members && node.members.length > 0) { - this.#throwUnlessAllowInvalidAST( + this.#throwError( node.members[0], 'A mapped type may not declare properties or methods.', ); @@ -3009,19 +3000,30 @@ export class Converter { }); } - const result = this.createNode(node, { - type: AST_NODE_TYPES.TSImportType, - range, - argument: this.convertChild(node.argument), - options, - qualifier: this.convertChild(node.qualifier), - typeArguments: node.typeArguments - ? this.convertTypeArgumentsToTypeParameterInstantiation( - node.typeArguments, - node, - ) - : null, - }); + const argument = this.convertChild(node.argument); + const source = argument.literal; + + const result = this.createNode( + node, + this.#withDeprecatedGetter( + { + type: AST_NODE_TYPES.TSImportType, + range, + options, + qualifier: this.convertChild(node.qualifier), + source, + typeArguments: node.typeArguments + ? this.convertTypeArgumentsToTypeParameterInstantiation( + node.typeArguments, + node, + ) + : null, + }, + 'argument', + 'source', + argument, + ), + ); if (node.isTypeOf) { return this.createNode(node, { @@ -3061,7 +3063,7 @@ export class Converter { case SyntaxKind.EnumMember: { const computed = node.name.kind === ts.SyntaxKind.ComputedPropertyName; if (computed) { - this.#throwUnlessAllowInvalidAST( + this.#throwError( node.name, 'Computed property names are not allowed in enums.', ); @@ -3071,7 +3073,7 @@ export class Converter { node.name.kind === SyntaxKind.NumericLiteral || node.name.kind === SyntaxKind.BigIntLiteral ) { - this.#throwUnlessAllowInvalidAST( + this.#throwError( node.name, 'An enum member cannot have a numeric name.', ); @@ -3116,13 +3118,13 @@ export class Converter { body == null || body.type === AST_NODE_TYPES.TSModuleDeclaration ) { - this.#throwUnlessAllowInvalidAST( + this.#throwError( node.body ?? node, 'Expected a valid module body', ); } if (id.type !== AST_NODE_TYPES.Identifier) { - this.#throwUnlessAllowInvalidAST( + this.#throwError( node.name, 'global module augmentation must have an Identifier id', ); @@ -3154,10 +3156,10 @@ export class Converter { // with the innermost node's body as the actual node body. if (node.body == null) { - this.#throwUnlessAllowInvalidAST(node, 'Expected a module body'); + this.#throwError(node, 'Expected a module body'); } if (node.name.kind !== ts.SyntaxKind.Identifier) { - this.#throwUnlessAllowInvalidAST( + this.#throwError( node.name, '`namespace`s must have an Identifier id', ); diff --git a/packages/typescript-estree/src/parseSettings/inferSingleRun.ts b/packages/typescript-estree/src/parseSettings/inferSingleRun.ts index 8007e6ccd66a..bb4fc04ec540 100644 --- a/packages/typescript-estree/src/parseSettings/inferSingleRun.ts +++ b/packages/typescript-estree/src/parseSettings/inferSingleRun.ts @@ -18,13 +18,13 @@ export function inferSingleRun(options: TSESTreeOptions | undefined): boolean { // https://github.com/typescript-eslint/typescript-eslint/issues/9504 // There's no support (yet?) for extraFileExtensions in single-run hosts. // Only watch program hosts and project service can support that. - if (options?.extraFileExtensions?.length) { + if (options?.extraFileExtensions?.length && options.project) { return false; } if ( // single-run implies type-aware linting - no projects means we can't be in single-run mode - options?.project == null || + (options?.project == null && !options?.projectService) || // programs passed via options means the user should be managing the programs, so we shouldn't // be creating our own single-run programs accidentally options.programs != null diff --git a/packages/typescript-estree/src/parseSettings/resolveProjectList.ts b/packages/typescript-estree/src/parseSettings/resolveProjectList.ts index f29bf0026469..a5deafd35ae5 100644 --- a/packages/typescript-estree/src/parseSettings/resolveProjectList.ts +++ b/packages/typescript-estree/src/parseSettings/resolveProjectList.ts @@ -1,6 +1,5 @@ import debug from 'debug'; -import { sync as globSync } from 'fast-glob'; -import isGlob from 'is-glob'; +import { globSync, isDynamicPattern } from 'tinyglobby'; import type { CanonicalPath } from '../create-program/shared'; import type { TSESTreeOptions } from '../parser-options'; @@ -57,10 +56,7 @@ export function resolveProjectList( const projectFolderIgnoreList = ( options.projectFolderIgnoreList ?? ['**/node_modules/**'] - ) - .filter(folder => typeof folder === 'string') - // prefix with a ! for not match glob - .map(folder => (folder.startsWith('!') ? folder : `!${folder}`)); + ).filter(folder => typeof folder === 'string'); const cacheKey = getHash({ project: sanitizedProjects, @@ -86,18 +82,22 @@ export function resolveProjectList( } // Transform glob patterns into paths - const nonGlobProjects = sanitizedProjects.filter(project => !isGlob(project)); - const globProjects = sanitizedProjects.filter(project => isGlob(project)); + const nonGlobProjects = sanitizedProjects.filter( + project => !isDynamicPattern(project), + ); + const globProjects = sanitizedProjects.filter(project => + isDynamicPattern(project), + ); let globProjectPaths: string[] = []; if (globProjects.length > 0) { - // Although fast-glob supports multiple patterns, fast-glob returns arbitrary order of results - // to improve performance. To ensure the order is correct, we need to call fast-glob for each pattern + // To ensure the order is correct, we need to glob for each pattern // separately and then concatenate the results in patterns' order. globProjectPaths = globProjects.flatMap(pattern => globSync(pattern, { cwd: options.tsconfigRootDir, + expandDirectories: false, ignore: projectFolderIgnoreList, }), ); diff --git a/packages/typescript-estree/src/parser-options.ts b/packages/typescript-estree/src/parser-options.ts index a1841a828d48..f643ccf19bcf 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, TSNode, TSToken } from './ts-estree'; +import type { TSESTree, TSESTreeToTSNode, 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 a88a3615d9f8..077382409f3a 100644 --- a/packages/typescript-estree/src/semantic-or-syntactic-errors.ts +++ b/packages/typescript-estree/src/semantic-or-syntactic-errors.ts @@ -1,9 +1,4 @@ -import type { - Diagnostic, - DiagnosticWithLocation, - Program, - SourceFile, -} from 'typescript'; +import type { Diagnostic, Program, SourceFile } from 'typescript'; import { flattenDiagnosticMessageText, sys } from 'typescript'; @@ -59,8 +54,8 @@ export function getFirstSemanticOrSyntacticError( } function allowlistSupportedDiagnostics( - diagnostics: readonly (Diagnostic | DiagnosticWithLocation)[], -): readonly (Diagnostic | DiagnosticWithLocation)[] { + diagnostics: readonly Diagnostic[], +): readonly Diagnostic[] { 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/typescript-estree/tests/lib/inferSingleRun.test.ts b/packages/typescript-estree/tests/lib/inferSingleRun.test.ts index 2fe53da89076..0701ddd168b5 100644 --- a/packages/typescript-estree/tests/lib/inferSingleRun.test.ts +++ b/packages/typescript-estree/tests/lib/inferSingleRun.test.ts @@ -143,6 +143,17 @@ describe(inferSingleRun, () => { expect(actual).toBe(false); }); + it('returns true when options.extraFileExtensions contains entries and projectService is true', () => { + vi.stubEnv('CI', 'true'); + + const actual = inferSingleRun({ + extraFileExtensions: ['.vue'], + projectService: true, + }); + + expect(actual).toBe(true); + }); + it('returns false when there is no way to infer singleRun', () => { const actual = inferSingleRun({ programs: null, @@ -157,4 +168,11 @@ describe(inferSingleRun, () => { expect(actual).toBe(false); }); + + it('returns true for project service in single run', () => { + vi.stubEnv('CI', 'true'); + const actual = inferSingleRun({ projectService: true }); + + expect(actual).toBe(true); + }); }); diff --git a/packages/typescript-estree/tests/lib/parse.test.ts b/packages/typescript-estree/tests/lib/parse.test.ts index 421287ff182b..331cd2308e16 100644 --- a/packages/typescript-estree/tests/lib/parse.test.ts +++ b/packages/typescript-estree/tests/lib/parse.test.ts @@ -1,8 +1,8 @@ import type { CacheDurationSeconds } from '@typescript-eslint/types'; import debug from 'debug'; -import * as fastGlobModule from 'fast-glob'; import { join, resolve } from 'node:path'; +import * as tinyGlobbyModule from 'tinyglobby'; import type { TSESTreeOptions } from '../../src/parser-options'; @@ -39,20 +39,21 @@ vi.mock(import('typescript'), async importOriginal => { }; }); -vi.mock('fast-glob', async importOriginal => { - const fastGlob = await importOriginal(); +vi.mock('tinyglobby', async importOriginal => { + const tinyglobby = await importOriginal(); return { - ...fastGlob, - default: fastGlob.default, - sync: vi.fn(fastGlob.sync), + ...tinyglobby, + // eslint-disable-next-line @typescript-eslint/no-deprecated -- see #10215 + globSync: vi.fn(tinyglobby.globSync), }; }); const createDefaultCompilerOptionsFromExtra = vi.mocked( sharedParserUtilsModule.createDefaultCompilerOptionsFromExtra, ); -const fastGlobSyncMock = vi.mocked(fastGlobModule.sync); +// eslint-disable-next-line @typescript-eslint/no-deprecated -- see #10215 +const globSyncMock = vi.mocked(tinyGlobbyModule.globSync); /** * Aligns paths between environments, node for windows uses `\`, for linux and mac uses `/` @@ -831,11 +832,11 @@ describe(parser.parseAndGenerateServices, () => { () => { describe('glob', () => { const project = ['./**/tsconfig.json', './**/tsconfig.extra.json']; - // fast-glob returns arbitrary order of results to improve performance. - // `resolveProjectList()` calls fast-glob for each pattern to ensure the + // tinyglobby returns arbitrary order of results to improve performance. + // `resolveProjectList()` runs a glob for each pattern to ensure the // order is correct. // Thus the expected call time of spy is the number of patterns. - const expectFastGlobCalls = project.length; + const expectedGlobCount = project.length; function doParse(lifetime: CacheDurationSeconds): void { parser.parseAndGenerateServices('const x = 1', { cacheLifetime: { @@ -850,50 +851,46 @@ describe(parser.parseAndGenerateServices, () => { it('should cache globs if the lifetime is non-zero', () => { doParse(30); - expect(fastGlobSyncMock).toHaveBeenCalledTimes(expectFastGlobCalls); + expect(globSyncMock).toHaveBeenCalledTimes(expectedGlobCount); doParse(30); - // shouldn't call fast-glob again due to the caching - expect(fastGlobSyncMock).toHaveBeenCalledTimes(expectFastGlobCalls); + // shouldn't glob again due to the caching + expect(globSyncMock).toHaveBeenCalledTimes(expectedGlobCount); }); it('should not cache globs if the lifetime is zero', () => { doParse(0); - expect(fastGlobSyncMock).toHaveBeenCalledTimes(expectFastGlobCalls); + expect(globSyncMock).toHaveBeenCalledTimes(expectedGlobCount); doParse(0); - // should call fast-glob again because we specified immediate cache expiry - expect(fastGlobSyncMock).toHaveBeenCalledTimes( - expectFastGlobCalls * 2, - ); + // should glob again because we specified immediate cache expiry + expect(globSyncMock).toHaveBeenCalledTimes(2 * expectedGlobCount); }); it('should evict the cache if the entry expires', () => { hrtimeSpy.mockReturnValueOnce([1, 0]); doParse(30); - expect(fastGlobSyncMock).toHaveBeenCalledTimes(expectFastGlobCalls); + expect(globSyncMock).toHaveBeenCalledTimes(expectedGlobCount); // wow so much time has passed hrtimeSpy.mockReturnValueOnce([Number.MAX_VALUE, 0]); doParse(30); - // shouldn't call fast-glob again due to the caching - expect(fastGlobSyncMock).toHaveBeenCalledTimes( - expectFastGlobCalls * 2, - ); + // shouldn't glob again due to the caching + expect(globSyncMock).toHaveBeenCalledTimes(2 * expectedGlobCount); }); it('should infinitely cache if passed Infinity', () => { hrtimeSpy.mockReturnValueOnce([1, 0]); doParse('Infinity'); - expect(fastGlobSyncMock).toHaveBeenCalledTimes(expectFastGlobCalls); + expect(globSyncMock).toHaveBeenCalledTimes(expectedGlobCount); // wow so much time has passed hrtimeSpy.mockReturnValueOnce([Number.MAX_VALUE, 0]); doParse('Infinity'); - // shouldn't call fast-glob again due to the caching - expect(fastGlobSyncMock).toHaveBeenCalledTimes(expectFastGlobCalls); + // shouldn't glob again due to the caching + expect(globSyncMock).toHaveBeenCalledTimes(expectedGlobCount); }); }); }, diff --git a/packages/typescript-estree/tsconfig.json b/packages/typescript-estree/tsconfig.json index 77cec8e6ba10..d4d0929e1955 100644 --- a/packages/typescript-estree/tsconfig.json +++ b/packages/typescript-estree/tsconfig.json @@ -3,18 +3,6 @@ "files": [], "include": [], "references": [ - { - "path": "../project-service" - }, - { - "path": "../tsconfig-utils" - }, - { - "path": "../visitor-keys" - }, - { - "path": "../types" - }, { "path": "./tsconfig.build.json" }, diff --git a/packages/utils/CHANGELOG.md b/packages/utils/CHANGELOG.md index 7caa39657a3b..3f48c888c19a 100644 --- a/packages/utils/CHANGELOG.md +++ b/packages/utils/CHANGELOG.md @@ -1,3 +1,16 @@ +## 8.48.0 (2025-11-24) + +### 🚀 Features + +- **eslint-plugin:** [no-redundant-type-constituents] use assignability checking for redundancy checks ([#10744](https://github.com/typescript-eslint/typescript-eslint/pull/10744)) + +### ❤️ Thank You + +- Josh Goldberg +- mdm317 @gen-ip-1 + +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.47.0 (2025-11-17) This was a version bump only for utils to align it with other projects, there were no code changes. diff --git a/packages/utils/package.json b/packages/utils/package.json index 3621d7a1e47d..54907514f126 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/utils", - "version": "8.47.0", + "version": "8.48.0", "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.47.0", - "@typescript-eslint/types": "8.47.0", - "@typescript-eslint/typescript-estree": "8.47.0" + "@typescript-eslint/scope-manager": "8.48.0", + "@typescript-eslint/types": "8.48.0", + "@typescript-eslint/typescript-estree": "8.48.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", diff --git a/packages/utils/src/ts-eslint/Config.ts b/packages/utils/src/ts-eslint/Config.ts index 95ab05d9f2f2..a4cf356e2dbc 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 = 'commonjs' | ParserOptionsTypes.SourceType; + export type SourceType = 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 | undefined; + ecmaVersion?: EcmaVersion; /** * An object specifying additional objects that should be added to the global scope during linting. */ diff --git a/packages/utils/tsconfig.json b/packages/utils/tsconfig.json index bda7a07530ab..d4d0929e1955 100644 --- a/packages/utils/tsconfig.json +++ b/packages/utils/tsconfig.json @@ -3,15 +3,6 @@ "files": [], "include": [], "references": [ - { - "path": "../typescript-estree" - }, - { - "path": "../types" - }, - { - "path": "../scope-manager" - }, { "path": "./tsconfig.build.json" }, diff --git a/packages/visitor-keys/CHANGELOG.md b/packages/visitor-keys/CHANGELOG.md index 377db5b76353..ab8735eaa0a3 100644 --- a/packages/visitor-keys/CHANGELOG.md +++ b/packages/visitor-keys/CHANGELOG.md @@ -1,3 +1,9 @@ +## 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. + +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.47.0 (2025-11-17) 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 7e9159da6db3..06564f9dd090 100644 --- a/packages/visitor-keys/package.json +++ b/packages/visitor-keys/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/visitor-keys", - "version": "8.47.0", + "version": "8.48.0", "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.47.0", + "@typescript-eslint/types": "8.48.0", "eslint-visitor-keys": "^4.2.1" }, "devDependencies": { diff --git a/packages/visitor-keys/src/visitor-keys.ts b/packages/visitor-keys/src/visitor-keys.ts index 8fd0d512ac98..09ceae691313 100644 --- a/packages/visitor-keys/src/visitor-keys.ts +++ b/packages/visitor-keys/src/visitor-keys.ts @@ -213,7 +213,7 @@ const additionalKeys: AdditionalKeys = { TSExternalModuleReference: ['expression'], TSFunctionType: SharedVisitorKeys.FunctionType, TSImportEqualsDeclaration: ['id', 'moduleReference'], - TSImportType: ['argument', 'options', 'qualifier', 'typeArguments'], + TSImportType: ['source', 'options', 'qualifier', 'typeArguments'], TSIndexedAccessType: ['objectType', 'indexType'], TSIndexSignature: ['parameters', 'typeAnnotation'], TSInferType: ['typeParameter'], diff --git a/packages/visitor-keys/tsconfig.json b/packages/visitor-keys/tsconfig.json index d89a8a4ec896..d4d0929e1955 100644 --- a/packages/visitor-keys/tsconfig.json +++ b/packages/visitor-keys/tsconfig.json @@ -3,9 +3,6 @@ "files": [], "include": [], "references": [ - { - "path": "../types" - }, { "path": "./tsconfig.build.json" }, diff --git a/packages/website-eslint/tsconfig.json b/packages/website-eslint/tsconfig.json index 1f518d0e3023..4398f303dc7d 100644 --- a/packages/website-eslint/tsconfig.json +++ b/packages/website-eslint/tsconfig.json @@ -3,21 +3,6 @@ "files": [], "include": [], "references": [ - { - "path": "../visitor-keys" - }, - { - "path": "../typescript-estree" - }, - { - "path": "../scope-manager" - }, - { - "path": "../parser" - }, - { - "path": "../eslint-plugin" - }, { "path": "./tsconfig.build.json" } diff --git a/packages/website/src/components/ast/DataRenderer.tsx b/packages/website/src/components/ast/DataRenderer.tsx index 4619fd579bc1..e684e4f312df 100644 --- a/packages/website/src/components/ast/DataRenderer.tsx +++ b/packages/website/src/components/ast/DataRenderer.tsx @@ -30,8 +30,7 @@ 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 18fb35d3ce00..fac9734b0936 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'] | undefined; + let esQuery: ConfigModel['esQuery']; if (searchParams.has('esQuery')) { esQuery = JSON.parse( readQueryParam(searchParams.get('esQuery'), ''), diff --git a/packages/website/tsconfig.json b/packages/website/tsconfig.json index d3b0dd5bcc67..4398f303dc7d 100644 --- a/packages/website/tsconfig.json +++ b/packages/website/tsconfig.json @@ -3,30 +3,6 @@ "files": [], "include": [], "references": [ - { - "path": "../website-eslint" - }, - { - "path": "../utils" - }, - { - "path": "../typescript-estree" - }, - { - "path": "../types" - }, - { - "path": "../scope-manager" - }, - { - "path": "../rule-schema-to-typescript-types" - }, - { - "path": "../eslint-plugin" - }, - { - "path": "../parser" - }, { "path": "./tsconfig.build.json" } diff --git a/yarn.lock b/yarn.lock index 41cffe290e31..08d0e2f2ee99 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4249,28 +4249,28 @@ __metadata: languageName: node linkType: hard -"@microsoft/api-extractor-model@npm:7.31.3": - version: 7.31.3 - resolution: "@microsoft/api-extractor-model@npm:7.31.3" +"@microsoft/api-extractor-model@npm:7.32.1": + version: 7.32.1 + resolution: "@microsoft/api-extractor-model@npm:7.32.1" dependencies: - "@microsoft/tsdoc": ~0.15.1 - "@microsoft/tsdoc-config": ~0.17.1 - "@rushstack/node-core-library": 5.18.0 - checksum: 8f97f164e1191f3093505e1398e73dd3adb7b5a1df8d3ee7456769345e04b5b7d487ff6325bbb12e7ac513be8d0c96575672896085f0777bea9666a66273522e + "@microsoft/tsdoc": ~0.16.0 + "@microsoft/tsdoc-config": ~0.18.0 + "@rushstack/node-core-library": 5.19.0 + checksum: 042c22c5c7d39c0b481f9335971eb6f8f492cc1d1dfaf2b112a374341248def1407b0fae73da5fc0240a1edd421c04d677eb86b03b3c8018751729932ad18cff languageName: node linkType: hard "@microsoft/api-extractor@npm:^7.47.11": - version: 7.54.0 - resolution: "@microsoft/api-extractor@npm:7.54.0" + version: 7.55.1 + resolution: "@microsoft/api-extractor@npm:7.55.1" dependencies: - "@microsoft/api-extractor-model": 7.31.3 - "@microsoft/tsdoc": ~0.15.1 - "@microsoft/tsdoc-config": ~0.17.1 - "@rushstack/node-core-library": 5.18.0 + "@microsoft/api-extractor-model": 7.32.1 + "@microsoft/tsdoc": ~0.16.0 + "@microsoft/tsdoc-config": ~0.18.0 + "@rushstack/node-core-library": 5.19.0 "@rushstack/rig-package": 0.6.0 - "@rushstack/terminal": 0.19.3 - "@rushstack/ts-command-line": 5.1.3 + "@rushstack/terminal": 0.19.4 + "@rushstack/ts-command-line": 5.1.4 diff: ~8.0.2 lodash: ~4.17.15 minimatch: 10.0.3 @@ -4280,26 +4280,26 @@ __metadata: typescript: 5.8.2 bin: api-extractor: bin/api-extractor - checksum: 53c396675dc0622d71dc484fd2918bc910ef3144303d6659d416b14eeaf2ac0f18e90a5aeb88b6ac5f116fe87927fcbd19a9e69a409c64e4c3a4a88e8ded32e0 + checksum: edd7ee4c5b953735a3c9c11c35c8b4b27288b2a84aec456be6a584e3d74ad820db92e17e815319e0cdf6566db7d8d0218fc082b4fbdeaca40f0c3ab6a6bf8a9f languageName: node linkType: hard -"@microsoft/tsdoc-config@npm:~0.17.1": - version: 0.17.1 - resolution: "@microsoft/tsdoc-config@npm:0.17.1" +"@microsoft/tsdoc-config@npm:~0.18.0": + version: 0.18.0 + resolution: "@microsoft/tsdoc-config@npm:0.18.0" dependencies: - "@microsoft/tsdoc": 0.15.1 + "@microsoft/tsdoc": 0.16.0 ajv: ~8.12.0 jju: ~1.4.0 resolve: ~1.22.2 - checksum: 19d3301af62c62eac5b3c244564070b18c529c0985d299b9e93d04cc75d2c1342458063d494c941f814c7154463ee364acdc76ea552db92cbbb0a3e28bbca87c + checksum: 2ecf902513e4e084b5698f62f89ba653d050d49f57f0daa34800770e3f00e88bf239a21790c0974082e0b358fa147d45b36d7653794e03afd2258b50a8a1daba languageName: node linkType: hard -"@microsoft/tsdoc@npm:0.15.1, @microsoft/tsdoc@npm:~0.15.1": - version: 0.15.1 - resolution: "@microsoft/tsdoc@npm:0.15.1" - checksum: 526f125c48b4e5511571ee552ff38691405131c0b72df85f091b1aa47571315e7ba5258cd9f48c41b8ef80f2c1f489e9b09c8b1fcc1599b7f8a35f917e03ec65 +"@microsoft/tsdoc@npm:0.16.0, @microsoft/tsdoc@npm:~0.16.0": + version: 0.16.0 + resolution: "@microsoft/tsdoc@npm:0.16.0" + checksum: 8aece3371a45a18af4233a5d6f8ac94612c8baef65f782f925b0c1f5a98802f031e6bf8b487a849ceb35f4cc6c2ea15ba82a4497c72b50e5b33771ecd62729cd languageName: node linkType: hard @@ -4370,28 +4370,26 @@ __metadata: languageName: node linkType: hard -"@nx/devkit@npm:21.4.1": - version: 21.4.1 - resolution: "@nx/devkit@npm:21.4.1" +"@nx/devkit@npm:22.1.1": + version: 22.1.1 + resolution: "@nx/devkit@npm:22.1.1" dependencies: + "@zkochan/js-yaml": 0.0.7 ejs: ^3.1.7 enquirer: ~2.3.6 - ignore: ^5.0.4 minimatch: 9.0.3 - nx: 21.4.1 - semver: ^7.5.3 - tmp: ~0.2.1 + semver: ^7.6.3 tslib: ^2.3.0 yargs-parser: 21.1.1 peerDependencies: - nx: ">= 20 <= 22" - checksum: 37797c3d785de1068b6ae5a646d8ac1e716ce691c4b05fba489b9c89f432ce1ab716a3e27fe262f8d75cdcdec0a576594b34bee7d61c6b1a94d2ca9f9cfe83ed + nx: ">= 21 <= 23 || ^22.0.0-0" + checksum: f1a52bdf0dccefc7b96bcadbaf6b342e47557effc96c587418108ae82ff0cb32e47780b5f8c59d9aadcedf89fb5a53ed5715d711011df5542d346a251ffa647c languageName: node linkType: hard -"@nx/js@npm:21.4.1": - version: 21.4.1 - resolution: "@nx/js@npm:21.4.1" +"@nx/js@npm:22.1.1": + version: 22.1.1 + resolution: "@nx/js@npm:22.1.1" dependencies: "@babel/core": ^7.23.2 "@babel/plugin-proposal-decorators": ^7.22.7 @@ -4400,8 +4398,8 @@ __metadata: "@babel/preset-env": ^7.23.2 "@babel/preset-typescript": ^7.22.5 "@babel/runtime": ^7.22.6 - "@nx/devkit": 21.4.1 - "@nx/workspace": 21.4.1 + "@nx/devkit": 22.1.1 + "@nx/workspace": 22.1.1 "@zkochan/js-yaml": 0.0.7 babel-plugin-const-enum: ^1.0.1 babel-plugin-macros: ^3.1.0 @@ -4409,16 +4407,13 @@ __metadata: chalk: ^4.1.0 columnify: ^1.6.0 detect-port: ^1.5.1 - enquirer: ~2.3.6 ignore: ^5.0.4 js-tokens: ^4.0.0 jsonc-parser: 3.2.0 - npm-package-arg: 11.0.1 npm-run-path: ^4.0.1 - ora: 5.3.0 picocolors: ^1.1.0 picomatch: 4.0.2 - semver: ^7.5.3 + semver: ^7.6.3 source-map-support: 0.5.19 tinyglobby: ^0.2.12 tslib: ^2.3.0 @@ -4427,248 +4422,249 @@ __metadata: peerDependenciesMeta: verdaccio: optional: true - checksum: 5fc495473f2c522da73c7be62f0f59824bbf321dc6f151e2e3d9d23271a496c4a9f9f978c518843899046218334d3b44e2072277661572f952c8bc0a0b2f2674 + checksum: a60dca6157c3b097a542baf85be79da8821fc3cb28b594735845daecfade4674d2713bd14627be6ba0c6805e36ee1c0eb0a58f846c440d66230f591cbbf87318 languageName: node linkType: hard -"@nx/nx-darwin-arm64@npm:21.4.1": - version: 21.4.1 - resolution: "@nx/nx-darwin-arm64@npm:21.4.1" +"@nx/nx-darwin-arm64@npm:22.1.1": + version: 22.1.1 + resolution: "@nx/nx-darwin-arm64@npm:22.1.1" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@nx/nx-darwin-x64@npm:21.4.1": - version: 21.4.1 - resolution: "@nx/nx-darwin-x64@npm:21.4.1" +"@nx/nx-darwin-x64@npm:22.1.1": + version: 22.1.1 + resolution: "@nx/nx-darwin-x64@npm:22.1.1" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@nx/nx-freebsd-x64@npm:21.4.1": - version: 21.4.1 - resolution: "@nx/nx-freebsd-x64@npm:21.4.1" +"@nx/nx-freebsd-x64@npm:22.1.1": + version: 22.1.1 + resolution: "@nx/nx-freebsd-x64@npm:22.1.1" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@nx/nx-linux-arm-gnueabihf@npm:21.4.1": - version: 21.4.1 - resolution: "@nx/nx-linux-arm-gnueabihf@npm:21.4.1" +"@nx/nx-linux-arm-gnueabihf@npm:22.1.1": + version: 22.1.1 + resolution: "@nx/nx-linux-arm-gnueabihf@npm:22.1.1" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@nx/nx-linux-arm64-gnu@npm:21.4.1": - version: 21.4.1 - resolution: "@nx/nx-linux-arm64-gnu@npm:21.4.1" +"@nx/nx-linux-arm64-gnu@npm:22.1.1": + version: 22.1.1 + resolution: "@nx/nx-linux-arm64-gnu@npm:22.1.1" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@nx/nx-linux-arm64-musl@npm:21.4.1": - version: 21.4.1 - resolution: "@nx/nx-linux-arm64-musl@npm:21.4.1" +"@nx/nx-linux-arm64-musl@npm:22.1.1": + version: 22.1.1 + resolution: "@nx/nx-linux-arm64-musl@npm:22.1.1" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@nx/nx-linux-x64-gnu@npm:21.4.1": - version: 21.4.1 - resolution: "@nx/nx-linux-x64-gnu@npm:21.4.1" +"@nx/nx-linux-x64-gnu@npm:22.1.1": + version: 22.1.1 + resolution: "@nx/nx-linux-x64-gnu@npm:22.1.1" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@nx/nx-linux-x64-musl@npm:21.4.1": - version: 21.4.1 - resolution: "@nx/nx-linux-x64-musl@npm:21.4.1" +"@nx/nx-linux-x64-musl@npm:22.1.1": + version: 22.1.1 + resolution: "@nx/nx-linux-x64-musl@npm:22.1.1" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@nx/nx-win32-arm64-msvc@npm:21.4.1": - version: 21.4.1 - resolution: "@nx/nx-win32-arm64-msvc@npm:21.4.1" +"@nx/nx-win32-arm64-msvc@npm:22.1.1": + version: 22.1.1 + resolution: "@nx/nx-win32-arm64-msvc@npm:22.1.1" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@nx/nx-win32-x64-msvc@npm:21.4.1": - version: 21.4.1 - resolution: "@nx/nx-win32-x64-msvc@npm:21.4.1" +"@nx/nx-win32-x64-msvc@npm:22.1.1": + version: 22.1.1 + resolution: "@nx/nx-win32-x64-msvc@npm:22.1.1" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@nx/vite@npm:21.4.1": - version: 21.4.1 - resolution: "@nx/vite@npm:21.4.1" +"@nx/vitest@npm:22.1.1": + version: 22.1.1 + resolution: "@nx/vitest@npm:22.1.1" dependencies: - "@nx/devkit": 21.4.1 - "@nx/js": 21.4.1 + "@nx/devkit": 22.1.1 + "@nx/js": 22.1.1 "@phenomnomnominal/tsquery": ~5.0.1 - ajv: ^8.0.0 - enquirer: ~2.3.6 - picomatch: 4.0.2 semver: ^7.6.3 - tsconfig-paths: ^4.1.2 tslib: ^2.3.0 peerDependencies: - vite: ^5.0.0 || ^6.0.0 - vitest: ^1.3.1 || ^2.0.0 || ^3.0.0 - checksum: 40311ee8134f484d32785087c3bfc5bec250e956b6098bd42613add7342b0fe2fa385286e427e120f744835daf58bbf7b7dff32dcb07ee046ed2b11ea8eadc46 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vitest: ^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 + peerDependenciesMeta: + vite: + optional: true + vitest: + optional: true + checksum: e4372a5ffa35efaf9f0543b6e7bbebe79904a5f4c7353231f4829c4b3a3192bea415110ef358edd0fb6721d9c71e4da5c04858505455da4a50ae143d6e331c24 languageName: node linkType: hard -"@nx/workspace@npm:21.4.1": - version: 21.4.1 - resolution: "@nx/workspace@npm:21.4.1" +"@nx/workspace@npm:22.1.1": + version: 22.1.1 + resolution: "@nx/workspace@npm:22.1.1" dependencies: - "@nx/devkit": 21.4.1 + "@nx/devkit": 22.1.1 "@zkochan/js-yaml": 0.0.7 chalk: ^4.1.0 enquirer: ~2.3.6 - nx: 21.4.1 + nx: 22.1.1 picomatch: 4.0.2 semver: ^7.6.3 tslib: ^2.3.0 yargs-parser: 21.1.1 - checksum: fab3ca1f4c780191e5b8855df7a36dd687a6413de89677f11d4b89517421288db26a3d01d2d76fc1ceb551171a6cb72706dfa780ad408ec038d94311e4bb75eb + checksum: dd7174ba59ac2caf06bb15fd97159c0f14e5dd834623a933f601fcbd5d99a77dd540aa5c5316cc76731af6f2350a0f311cb1aee3b52323e5496ed64bd8870318 languageName: node linkType: hard -"@oxc-resolver/binding-android-arm-eabi@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-android-arm-eabi@npm:11.13.1" +"@oxc-resolver/binding-android-arm-eabi@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-android-arm-eabi@npm:11.13.2" conditions: os=android & cpu=arm languageName: node linkType: hard -"@oxc-resolver/binding-android-arm64@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-android-arm64@npm:11.13.1" +"@oxc-resolver/binding-android-arm64@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-android-arm64@npm:11.13.2" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@oxc-resolver/binding-darwin-arm64@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-darwin-arm64@npm:11.13.1" +"@oxc-resolver/binding-darwin-arm64@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-darwin-arm64@npm:11.13.2" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@oxc-resolver/binding-darwin-x64@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-darwin-x64@npm:11.13.1" +"@oxc-resolver/binding-darwin-x64@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-darwin-x64@npm:11.13.2" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@oxc-resolver/binding-freebsd-x64@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-freebsd-x64@npm:11.13.1" +"@oxc-resolver/binding-freebsd-x64@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-freebsd-x64@npm:11.13.2" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@oxc-resolver/binding-linux-arm-gnueabihf@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-linux-arm-gnueabihf@npm:11.13.1" +"@oxc-resolver/binding-linux-arm-gnueabihf@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-linux-arm-gnueabihf@npm:11.13.2" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@oxc-resolver/binding-linux-arm-musleabihf@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-linux-arm-musleabihf@npm:11.13.1" +"@oxc-resolver/binding-linux-arm-musleabihf@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-linux-arm-musleabihf@npm:11.13.2" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@oxc-resolver/binding-linux-arm64-gnu@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-linux-arm64-gnu@npm:11.13.1" +"@oxc-resolver/binding-linux-arm64-gnu@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-linux-arm64-gnu@npm:11.13.2" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@oxc-resolver/binding-linux-arm64-musl@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-linux-arm64-musl@npm:11.13.1" +"@oxc-resolver/binding-linux-arm64-musl@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-linux-arm64-musl@npm:11.13.2" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@oxc-resolver/binding-linux-ppc64-gnu@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-linux-ppc64-gnu@npm:11.13.1" +"@oxc-resolver/binding-linux-ppc64-gnu@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-linux-ppc64-gnu@npm:11.13.2" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@oxc-resolver/binding-linux-riscv64-gnu@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-linux-riscv64-gnu@npm:11.13.1" +"@oxc-resolver/binding-linux-riscv64-gnu@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-linux-riscv64-gnu@npm:11.13.2" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@oxc-resolver/binding-linux-riscv64-musl@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-linux-riscv64-musl@npm:11.13.1" +"@oxc-resolver/binding-linux-riscv64-musl@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-linux-riscv64-musl@npm:11.13.2" conditions: os=linux & cpu=riscv64 & libc=musl languageName: node linkType: hard -"@oxc-resolver/binding-linux-s390x-gnu@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-linux-s390x-gnu@npm:11.13.1" +"@oxc-resolver/binding-linux-s390x-gnu@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-linux-s390x-gnu@npm:11.13.2" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@oxc-resolver/binding-linux-x64-gnu@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-linux-x64-gnu@npm:11.13.1" +"@oxc-resolver/binding-linux-x64-gnu@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-linux-x64-gnu@npm:11.13.2" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@oxc-resolver/binding-linux-x64-musl@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-linux-x64-musl@npm:11.13.1" +"@oxc-resolver/binding-linux-x64-musl@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-linux-x64-musl@npm:11.13.2" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@oxc-resolver/binding-wasm32-wasi@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-wasm32-wasi@npm:11.13.1" +"@oxc-resolver/binding-wasm32-wasi@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-wasm32-wasi@npm:11.13.2" dependencies: "@napi-rs/wasm-runtime": ^1.0.7 conditions: cpu=wasm32 languageName: node linkType: hard -"@oxc-resolver/binding-win32-arm64-msvc@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-win32-arm64-msvc@npm:11.13.1" +"@oxc-resolver/binding-win32-arm64-msvc@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-win32-arm64-msvc@npm:11.13.2" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@oxc-resolver/binding-win32-ia32-msvc@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-win32-ia32-msvc@npm:11.13.1" +"@oxc-resolver/binding-win32-ia32-msvc@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-win32-ia32-msvc@npm:11.13.2" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@oxc-resolver/binding-win32-x64-msvc@npm:11.13.1": - version: 11.13.1 - resolution: "@oxc-resolver/binding-win32-x64-msvc@npm:11.13.1" +"@oxc-resolver/binding-win32-x64-msvc@npm:11.13.2": + version: 11.13.2 + resolution: "@oxc-resolver/binding-win32-x64-msvc@npm:11.13.2" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -4955,9 +4951,9 @@ __metadata: languageName: node linkType: hard -"@rushstack/node-core-library@npm:5.18.0": - version: 5.18.0 - resolution: "@rushstack/node-core-library@npm:5.18.0" +"@rushstack/node-core-library@npm:5.19.0": + version: 5.19.0 + resolution: "@rushstack/node-core-library@npm:5.19.0" dependencies: ajv: ~8.13.0 ajv-draft-04: ~1.0.0 @@ -4972,7 +4968,7 @@ __metadata: peerDependenciesMeta: "@types/node": optional: true - checksum: 153d1c31128e0afbf230b0d068e1d2b236afa867fec1ead934e38f533c3be292a54113401d4fa0fc5e4828bfaf8192051a050a1d24f34e7587770e78ca7eb4e3 + checksum: bd05352fe8439081364254534d5900d4d5ae8e0d5aed8cc2268f06b6620146d955c99869fa76ad20da040b0188e0011b6b205470a16f50d00c5e4da45d40a19f languageName: node linkType: hard @@ -4998,11 +4994,11 @@ __metadata: languageName: node linkType: hard -"@rushstack/terminal@npm:0.19.3": - version: 0.19.3 - resolution: "@rushstack/terminal@npm:0.19.3" +"@rushstack/terminal@npm:0.19.4": + version: 0.19.4 + resolution: "@rushstack/terminal@npm:0.19.4" dependencies: - "@rushstack/node-core-library": 5.18.0 + "@rushstack/node-core-library": 5.19.0 "@rushstack/problem-matcher": 0.1.1 supports-color: ~8.1.1 peerDependencies: @@ -5010,19 +5006,19 @@ __metadata: peerDependenciesMeta: "@types/node": optional: true - checksum: 4ba155ed7818883cd81745ceb5cf47763be525f179312d46c9a25f0fb62b50d7d8d14aa0120d3d9b5d85a7265b0b267f54205b1f552e4a1a4e7045869caad163 + checksum: 8410cf89d791645982559c546c49fb698f5fddccb671810e3a2f28d8eb514eb22c86633ca6eab13103d72828b4c65a3cf45abd8fb27a06beaf2310ca664a32a6 languageName: node linkType: hard -"@rushstack/ts-command-line@npm:5.1.3": - version: 5.1.3 - resolution: "@rushstack/ts-command-line@npm:5.1.3" +"@rushstack/ts-command-line@npm:5.1.4": + version: 5.1.4 + resolution: "@rushstack/ts-command-line@npm:5.1.4" dependencies: - "@rushstack/terminal": 0.19.3 + "@rushstack/terminal": 0.19.4 "@types/argparse": 1.0.38 argparse: ~1.0.9 string-argv: ~0.3.1 - checksum: 8daf8dd0aae062f8fae847b31566ef83812529985e6e4ed0eb8ae9f41d140c85737df1253f694223e886bf9ce4a9ee7ffa7abdf25f079e05bc379073660d15b9 + checksum: a87a6e0c2bf2cbdf949c7de91930bc18eac19cdcd424adaee3a894da05cda21233ae69c4fb1d0db4833a86e07fcc936069f5c35b1530c793be7c654a7e1b6aa9 languageName: node linkType: hard @@ -5734,13 +5730,6 @@ __metadata: languageName: node linkType: hard -"@types/is-glob@npm:^4.0.4": - version: 4.0.4 - resolution: "@types/is-glob@npm:4.0.4" - checksum: c790125e2d133d15c9783f6468995841cb06b5634b5c7b30aa32d23129f19d7dc271ec1a904bea4ca1e6a5ba19218a6602753d558f343b4fb8402fed25d17219 - languageName: node - linkType: hard - "@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0": version: 2.0.4 resolution: "@types/istanbul-lib-coverage@npm:2.0.4" @@ -6113,19 +6102,19 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/eslint-plugin@8.47.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.0, @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.47.0 - "@typescript-eslint/rule-tester": 8.47.0 - "@typescript-eslint/scope-manager": 8.47.0 - "@typescript-eslint/type-utils": 8.47.0 - "@typescript-eslint/utils": 8.47.0 - "@typescript-eslint/visitor-keys": 8.47.0 + "@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 "@vitest/coverage-v8": ^3.1.3 ajv: ^6.12.6 cross-fetch: "*" @@ -6148,7 +6137,7 @@ __metadata: unist-util-visit: ^5.0.0 vitest: ^3.1.3 peerDependencies: - "@typescript-eslint/parser": ^8.47.0 + "@typescript-eslint/parser": ^8.48.0 eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <6.0.0" languageName: unknown @@ -6164,14 +6153,14 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/parser@8.47.0, @typescript-eslint/parser@workspace:*, @typescript-eslint/parser@workspace:^, @typescript-eslint/parser@workspace:packages/parser": +"@typescript-eslint/parser@8.48.0, @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.47.0 - "@typescript-eslint/types": 8.47.0 - "@typescript-eslint/typescript-estree": 8.47.0 - "@typescript-eslint/visitor-keys": 8.47.0 + "@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 "@vitest/coverage-v8": ^3.1.3 debug: ^4.3.4 eslint: "*" @@ -6185,12 +6174,12 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/project-service@8.47.0, @typescript-eslint/project-service@workspace:packages/project-service": +"@typescript-eslint/project-service@8.48.0, @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.47.0 - "@typescript-eslint/types": ^8.47.0 + "@typescript-eslint/tsconfig-utils": ^8.48.0 + "@typescript-eslint/types": ^8.48.0 "@vitest/coverage-v8": ^3.1.3 debug: ^4.3.4 rimraf: "*" @@ -6201,12 +6190,12 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/rule-schema-to-typescript-types@8.47.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.0, @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.47.0 - "@typescript-eslint/utils": 8.47.0 + "@typescript-eslint/type-utils": 8.48.0 + "@typescript-eslint/utils": 8.48.0 "@vitest/coverage-v8": ^3.1.3 eslint: "*" natural-compare: ^1.4.0 @@ -6216,15 +6205,15 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/rule-tester@8.47.0, @typescript-eslint/rule-tester@workspace:*, @typescript-eslint/rule-tester@workspace:packages/rule-tester": +"@typescript-eslint/rule-tester@8.48.0, @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.47.0 - "@typescript-eslint/typescript-estree": 8.47.0 - "@typescript-eslint/utils": 8.47.0 + "@typescript-eslint/parser": 8.48.0 + "@typescript-eslint/typescript-estree": 8.48.0 + "@typescript-eslint/utils": 8.48.0 "@vitest/coverage-v8": ^3.1.3 ajv: ^6.12.6 eslint: "*" @@ -6239,13 +6228,13 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/scope-manager@8.47.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.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": version: 0.0.0-use.local resolution: "@typescript-eslint/scope-manager@workspace:packages/scope-manager" dependencies: - "@typescript-eslint/types": 8.47.0 - "@typescript-eslint/typescript-estree": 8.47.0 - "@typescript-eslint/visitor-keys": 8.47.0 + "@typescript-eslint/types": 8.48.0 + "@typescript-eslint/typescript-estree": 8.48.0 + "@typescript-eslint/visitor-keys": 8.48.0 "@vitest/coverage-v8": ^3.1.3 "@vitest/pretty-format": ^3.1.3 eslint: "*" @@ -6256,7 +6245,7 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/tsconfig-utils@8.47.0, @typescript-eslint/tsconfig-utils@^8.47.0, @typescript-eslint/tsconfig-utils@workspace:packages/tsconfig-utils": +"@typescript-eslint/tsconfig-utils@8.48.0, @typescript-eslint/tsconfig-utils@^8.48.0, @typescript-eslint/tsconfig-utils@workspace:packages/tsconfig-utils": version: 0.0.0-use.local resolution: "@typescript-eslint/tsconfig-utils@workspace:packages/tsconfig-utils" dependencies: @@ -6269,14 +6258,14 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/type-utils@8.47.0, @typescript-eslint/type-utils@workspace:*, @typescript-eslint/type-utils@workspace:packages/type-utils": +"@typescript-eslint/type-utils@8.48.0, @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.47.0 - "@typescript-eslint/types": 8.47.0 - "@typescript-eslint/typescript-estree": 8.47.0 - "@typescript-eslint/utils": 8.47.0 + "@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 "@vitest/coverage-v8": ^3.1.3 ajv: ^6.12.6 debug: ^4.3.4 @@ -6291,7 +6280,7 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/types@8.47.0, @typescript-eslint/types@^8.11.0, @typescript-eslint/types@^8.34.1, @typescript-eslint/types@^8.47.0, @typescript-eslint/types@workspace:*, @typescript-eslint/types@workspace:^, @typescript-eslint/types@workspace:packages/types": +"@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": version: 0.0.0-use.local resolution: "@typescript-eslint/types@workspace:packages/types" dependencies: @@ -6312,10 +6301,10 @@ __metadata: "@eslint/compat": ^1.2.4 "@eslint/eslintrc": ^3.2.0 "@eslint/js": ^9.26.0 - "@nx/devkit": 21.4.1 - "@nx/js": 21.4.1 - "@nx/vite": 21.4.1 - "@nx/workspace": 21.4.1 + "@nx/devkit": 22.1.1 + "@nx/js": 22.1.1 + "@nx/vitest": 22.1.1 + "@nx/workspace": 22.1.1 "@swc/core": ^1.4.12 "@types/debug": ^4.1.12 "@types/eslint-plugin-jsx-a11y": ^6.10.0 @@ -6351,38 +6340,36 @@ __metadata: knip: ^5.41.1 lint-staged: ^15.2.2 markdownlint-cli: ^0.45.0 - nx: 21.4.1 + nx: 22.1.1 prettier: 3.6.2 rimraf: ^5.0.5 semver: 7.7.0 tsx: "*" typescript: ">=4.8.4 <6.0.0" typescript-eslint: "workspace:^" - vite: ^6.3.5 + vite: 7.2.4 vitest: ^3.1.3 yargs: 17.7.2 yarn-berry-deduplicate: ^6.1.3 languageName: unknown linkType: soft -"@typescript-eslint/typescript-estree@8.47.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.0, @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: - "@types/is-glob": ^4.0.4 - "@typescript-eslint/project-service": 8.47.0 - "@typescript-eslint/tsconfig-utils": 8.47.0 - "@typescript-eslint/types": 8.47.0 - "@typescript-eslint/visitor-keys": 8.47.0 + "@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 "@vitest/coverage-v8": ^3.1.3 debug: ^4.3.4 eslint: "*" - fast-glob: ^3.3.2 glob: "*" - is-glob: ^4.0.3 minimatch: ^9.0.4 rimraf: "*" semver: ^7.6.0 + tinyglobby: ^0.2.15 ts-api-utils: ^2.1.0 typescript: "*" vitest: ^3.1.3 @@ -6391,14 +6378,14 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/utils@8.47.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.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": 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.47.0 - "@typescript-eslint/types": 8.47.0 - "@typescript-eslint/typescript-estree": 8.47.0 + "@typescript-eslint/scope-manager": 8.48.0 + "@typescript-eslint/types": 8.48.0 + "@typescript-eslint/typescript-estree": 8.48.0 "@vitest/coverage-v8": ^3.1.3 eslint: "*" rimraf: "*" @@ -6410,11 +6397,11 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/visitor-keys@8.47.0, @typescript-eslint/visitor-keys@workspace:*, @typescript-eslint/visitor-keys@workspace:packages/visitor-keys": +"@typescript-eslint/visitor-keys@8.48.0, @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.47.0 + "@typescript-eslint/types": 8.48.0 "@vitest/coverage-v8": ^3.1.3 eslint: "*" eslint-visitor-keys: ^4.2.1 @@ -7459,14 +7446,14 @@ __metadata: languageName: node linkType: hard -"axios@npm:^1.8.3": - version: 1.8.4 - resolution: "axios@npm:1.8.4" +"axios@npm:^1.12.0": + version: 1.13.2 + resolution: "axios@npm:1.13.2" dependencies: follow-redirects: ^1.15.6 - form-data: ^4.0.0 + form-data: ^4.0.4 proxy-from-env: ^1.1.0 - checksum: e901dc1730bdcd769839b3d93ae6d6457a53d79b19a0eb623ebfea333441259ab51e63ca118baa47a5156567401466ac739f31087b4ee5e6770ab2e227484538 + checksum: 057d0204d5930e2969f0bccb9f0752745b1524a36994667833195e7e1a82f245d660752ba8517b2dbea17e9e4ed0479f10b80c5fe45edd0b5a0df645c0060386 languageName: node linkType: hard @@ -7772,15 +7759,6 @@ __metadata: languageName: node linkType: hard -"builtins@npm:^5.0.0": - version: 5.0.1 - resolution: "builtins@npm:5.0.1" - dependencies: - semver: ^7.0.0 - checksum: 66d204657fe36522822a95b288943ad11b58f5eaede235b11d8c4edaa28ce4800087d44a2681524c340494aadb120a0068011acabe99d30e8f11a7d826d83515 - languageName: node - linkType: hard - "bytes@npm:3.0.0": version: 3.0.0 resolution: "bytes@npm:3.0.0" @@ -10869,7 +10847,7 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.2, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.2, fast-glob@npm:^3.3.3": +"fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.2, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.3": version: 3.3.3 resolution: "fast-glob@npm:3.3.3" dependencies: @@ -10939,7 +10917,7 @@ __metadata: languageName: node linkType: hard -"fdir@npm:^6.4.4, fdir@npm:^6.5.0": +"fdir@npm:^6.5.0": version: 6.5.0 resolution: "fdir@npm:6.5.0" peerDependencies: @@ -11189,14 +11167,16 @@ __metadata: languageName: node linkType: hard -"form-data@npm:^4.0.0": - version: 4.0.0 - resolution: "form-data@npm:4.0.0" +"form-data@npm:^4.0.4": + version: 4.0.5 + resolution: "form-data@npm:4.0.5" dependencies: asynckit: ^0.4.0 combined-stream: ^1.0.8 + es-set-tostringtag: ^2.1.0 + hasown: ^2.0.2 mime-types: ^2.1.12 - checksum: 01135bf8675f9d5c61ff18e2e2932f719ca4de964e3be90ef4c36aacfc7b9cb2fceb5eca0b7e0190e3383fe51c5b37f4cb80b62ca06a99aaabfcfd6ac7c9328c + checksum: af8328413c16d0cded5fccc975a44d227c5120fd46a9e81de8acf619d43ed838414cc6d7792195b30b248f76a65246949a129a4dadd148721948f90cd6d4fb69 languageName: node linkType: hard @@ -12013,15 +11993,6 @@ __metadata: languageName: node linkType: hard -"hosted-git-info@npm:^7.0.0": - version: 7.0.1 - resolution: "hosted-git-info@npm:7.0.1" - dependencies: - lru-cache: ^10.0.1 - checksum: be5280f0a20d6153b47e1ab578e09f5ae8ad734301b3ed7e547dc88a6814d7347a4888db1b4f9635cc738e3c0ef1fbff02272aba7d07c75d4c5a50ff8d618db6 - languageName: node - linkType: hard - "hpack.js@npm:^2.1.6": version: 2.1.6 resolution: "hpack.js@npm:2.1.6" @@ -13284,14 +13255,14 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:^4.1.0, js-yaml@npm:~4.1.0": - version: 4.1.0 - resolution: "js-yaml@npm:4.1.0" +"js-yaml@npm:^4.1.0, js-yaml@npm:^4.1.1, js-yaml@npm:~4.1.0": + version: 4.1.1 + resolution: "js-yaml@npm:4.1.1" dependencies: argparse: ^2.0.1 bin: js-yaml: bin/js-yaml.js - checksum: c7830dfd456c3ef2c6e355cc5a92e6700ceafa1d14bba54497b34a99f0376cecbb3e9ac14d3e5849b426d5a5140709a66237a8c991c675431271c4ce5504151a + checksum: ea2339c6930fe048ec31b007b3c90be2714ab3e7defcc2c27ebf30c74fd940358f29070b4345af0019ef151875bf3bc3f8644bea1bab0372652b5044813ac02d languageName: node linkType: hard @@ -13472,20 +13443,20 @@ __metadata: linkType: hard "knip@npm:^5.41.1": - version: 5.68.0 - resolution: "knip@npm:5.68.0" + version: 5.70.0 + resolution: "knip@npm:5.70.0" dependencies: "@nodelib/fs.walk": ^1.2.3 fast-glob: ^3.3.3 formatly: ^0.3.0 jiti: ^2.6.0 - js-yaml: ^4.1.0 + js-yaml: ^4.1.1 minimist: ^1.2.8 - oxc-resolver: ^11.12.0 + oxc-resolver: ^11.13.2 picocolors: ^1.1.1 picomatch: ^4.0.1 - smol-toml: ^1.4.1 - strip-json-comments: 5.0.2 + smol-toml: ^1.5.2 + strip-json-comments: 5.0.3 zod: ^4.1.11 peerDependencies: "@types/node": ">=18" @@ -13493,7 +13464,7 @@ __metadata: bin: knip: bin/knip.js knip-bun: bin/knip-bun.js - checksum: a5ab5ae05c0f72f6dc5992908f252fa60cf7ba53aaa45af970f7882175de20ae98cec8f1813543a63cc0bd5353a701c37b20d47d80da62c3edb77a12234168ef + checksum: 541ec69426bd23c5d798bd6ce07fc2ef03eaffed5e24262bfa317c12c01a9ebf13f3c32cda6374464c5f39146bd548fd56efce5050f09ab3e9b2a902b43c8679 languageName: node linkType: hard @@ -13810,7 +13781,7 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": +"lru-cache@npm:^10.2.0": version: 10.2.0 resolution: "lru-cache@npm:10.2.0" checksum: eee7ddda4a7475deac51ac81d7dd78709095c6fa46e8350dc2d22462559a1faa3b81ed931d5464b13d48cbd7e08b46100b6f768c76833912bc444b99c37e25db @@ -15387,18 +15358,6 @@ __metadata: languageName: node linkType: hard -"npm-package-arg@npm:11.0.1": - version: 11.0.1 - resolution: "npm-package-arg@npm:11.0.1" - dependencies: - hosted-git-info: ^7.0.0 - proc-log: ^3.0.0 - semver: ^7.3.5 - validate-npm-package-name: ^5.0.0 - checksum: 60364504e04e34fc20b47ad192efc9181922bce0cb41fa81871b1b75748d8551725f61b2f9a2e3dffb1782d749a35313f5dc02c18c3987653990d486f223adf2 - languageName: node - linkType: hard - "npm-run-path@npm:^4.0.1": version: 4.0.1 resolution: "npm-run-path@npm:4.0.1" @@ -15464,25 +15423,25 @@ __metadata: languageName: node linkType: hard -"nx@npm:21.4.1": - version: 21.4.1 - resolution: "nx@npm:21.4.1" +"nx@npm:22.1.1": + version: 22.1.1 + resolution: "nx@npm:22.1.1" dependencies: "@napi-rs/wasm-runtime": 0.2.4 - "@nx/nx-darwin-arm64": 21.4.1 - "@nx/nx-darwin-x64": 21.4.1 - "@nx/nx-freebsd-x64": 21.4.1 - "@nx/nx-linux-arm-gnueabihf": 21.4.1 - "@nx/nx-linux-arm64-gnu": 21.4.1 - "@nx/nx-linux-arm64-musl": 21.4.1 - "@nx/nx-linux-x64-gnu": 21.4.1 - "@nx/nx-linux-x64-musl": 21.4.1 - "@nx/nx-win32-arm64-msvc": 21.4.1 - "@nx/nx-win32-x64-msvc": 21.4.1 + "@nx/nx-darwin-arm64": 22.1.1 + "@nx/nx-darwin-x64": 22.1.1 + "@nx/nx-freebsd-x64": 22.1.1 + "@nx/nx-linux-arm-gnueabihf": 22.1.1 + "@nx/nx-linux-arm64-gnu": 22.1.1 + "@nx/nx-linux-arm64-musl": 22.1.1 + "@nx/nx-linux-x64-gnu": 22.1.1 + "@nx/nx-linux-x64-musl": 22.1.1 + "@nx/nx-win32-arm64-msvc": 22.1.1 + "@nx/nx-win32-x64-msvc": 22.1.1 "@yarnpkg/lockfile": ^1.1.0 "@yarnpkg/parsers": 3.0.2 "@zkochan/js-yaml": 0.0.7 - axios: ^1.8.3 + axios: ^1.12.0 chalk: ^4.1.0 cli-cursor: 3.1.0 cli-spinners: 2.6.1 @@ -15493,7 +15452,7 @@ __metadata: figures: 3.2.0 flat: ^5.0.2 front-matter: ^4.0.2 - ignore: ^5.0.4 + ignore: ^7.0.5 jest-diff: ^30.0.2 jsonc-parser: 3.2.0 lines-and-columns: 2.0.3 @@ -15503,7 +15462,7 @@ __metadata: open: ^8.4.0 ora: 5.3.0 resolve.exports: 2.0.3 - semver: ^7.5.3 + semver: ^7.6.3 string-width: ^4.2.3 tar-stream: ~2.2.0 tmp: ~0.2.1 @@ -15545,7 +15504,7 @@ __metadata: bin: nx: bin/nx.js nx-cloud: bin/nx-cloud.js - checksum: babf4d271031fad5e300509310dd65cc1f3198c37a880ceb0c2eec105a61fcd903fa6fba4f597669b08b1c92445998f82f5f2cffab1a94ff45b015389bcb0515 + checksum: 4fac3e80797e883ce752031bf2cb6e98026f2f6801846648e267ae0aae96d0d23c1de5c180a838d3a6366b8fdedd7b959d6729870267e76686e22c20b1b37901 languageName: node linkType: hard @@ -15750,29 +15709,29 @@ __metadata: languageName: node linkType: hard -"oxc-resolver@npm:^11.12.0": - version: 11.13.1 - resolution: "oxc-resolver@npm:11.13.1" - dependencies: - "@oxc-resolver/binding-android-arm-eabi": 11.13.1 - "@oxc-resolver/binding-android-arm64": 11.13.1 - "@oxc-resolver/binding-darwin-arm64": 11.13.1 - "@oxc-resolver/binding-darwin-x64": 11.13.1 - "@oxc-resolver/binding-freebsd-x64": 11.13.1 - "@oxc-resolver/binding-linux-arm-gnueabihf": 11.13.1 - "@oxc-resolver/binding-linux-arm-musleabihf": 11.13.1 - "@oxc-resolver/binding-linux-arm64-gnu": 11.13.1 - "@oxc-resolver/binding-linux-arm64-musl": 11.13.1 - "@oxc-resolver/binding-linux-ppc64-gnu": 11.13.1 - "@oxc-resolver/binding-linux-riscv64-gnu": 11.13.1 - "@oxc-resolver/binding-linux-riscv64-musl": 11.13.1 - "@oxc-resolver/binding-linux-s390x-gnu": 11.13.1 - "@oxc-resolver/binding-linux-x64-gnu": 11.13.1 - "@oxc-resolver/binding-linux-x64-musl": 11.13.1 - "@oxc-resolver/binding-wasm32-wasi": 11.13.1 - "@oxc-resolver/binding-win32-arm64-msvc": 11.13.1 - "@oxc-resolver/binding-win32-ia32-msvc": 11.13.1 - "@oxc-resolver/binding-win32-x64-msvc": 11.13.1 +"oxc-resolver@npm:^11.13.2": + version: 11.13.2 + resolution: "oxc-resolver@npm:11.13.2" + dependencies: + "@oxc-resolver/binding-android-arm-eabi": 11.13.2 + "@oxc-resolver/binding-android-arm64": 11.13.2 + "@oxc-resolver/binding-darwin-arm64": 11.13.2 + "@oxc-resolver/binding-darwin-x64": 11.13.2 + "@oxc-resolver/binding-freebsd-x64": 11.13.2 + "@oxc-resolver/binding-linux-arm-gnueabihf": 11.13.2 + "@oxc-resolver/binding-linux-arm-musleabihf": 11.13.2 + "@oxc-resolver/binding-linux-arm64-gnu": 11.13.2 + "@oxc-resolver/binding-linux-arm64-musl": 11.13.2 + "@oxc-resolver/binding-linux-ppc64-gnu": 11.13.2 + "@oxc-resolver/binding-linux-riscv64-gnu": 11.13.2 + "@oxc-resolver/binding-linux-riscv64-musl": 11.13.2 + "@oxc-resolver/binding-linux-s390x-gnu": 11.13.2 + "@oxc-resolver/binding-linux-x64-gnu": 11.13.2 + "@oxc-resolver/binding-linux-x64-musl": 11.13.2 + "@oxc-resolver/binding-wasm32-wasi": 11.13.2 + "@oxc-resolver/binding-win32-arm64-msvc": 11.13.2 + "@oxc-resolver/binding-win32-ia32-msvc": 11.13.2 + "@oxc-resolver/binding-win32-x64-msvc": 11.13.2 dependenciesMeta: "@oxc-resolver/binding-android-arm-eabi": optional: true @@ -15812,7 +15771,7 @@ __metadata: optional: true "@oxc-resolver/binding-win32-x64-msvc": optional: true - checksum: 2aed976eac9d7142be0b518b95710ae6d988223064e49c5138951a334933a420b7176ec9a43f854b3e54d10a7d4fafc3cc5f15ea0aa297637165f47815f69151 + checksum: aacb79180c03a7ffc1976218362fa4a609a92e9640ce534d24ec32ecaef5547ea63383071aad1b83e98e7b7de5330d90175156505b7123ec06ab2c21b5f72bfd languageName: node linkType: hard @@ -17157,13 +17116,6 @@ __metadata: languageName: node linkType: hard -"proc-log@npm:^3.0.0": - version: 3.0.0 - resolution: "proc-log@npm:3.0.0" - checksum: 02b64e1b3919e63df06f836b98d3af002b5cd92655cab18b5746e37374bfb73e03b84fe305454614b34c25b485cc687a9eebdccf0242cda8fda2475dd2c97e02 - languageName: node - linkType: hard - "process-nextick-args@npm:~2.0.0": version: 2.0.1 resolution: "process-nextick-args@npm:2.0.1" @@ -18159,7 +18111,7 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^4.34.9, rollup@npm:^4.43.0": +"rollup@npm:^4.43.0": version: 4.52.5 resolution: "rollup@npm:4.52.5" dependencies: @@ -18447,7 +18399,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.0.0, semver@npm:^7.1.2, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3, semver@npm:^7.7.1, semver@npm:^7.7.2, semver@npm:^7.7.3": +"semver@npm:^7.1.2, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3, semver@npm:^7.7.1, semver@npm:^7.7.2, semver@npm:^7.7.3": version: 7.7.3 resolution: "semver@npm:7.7.3" bin: @@ -18820,10 +18772,10 @@ __metadata: languageName: node linkType: hard -"smol-toml@npm:^1.4.1, smol-toml@npm:^1.4.2": - version: 1.4.2 - resolution: "smol-toml@npm:1.4.2" - checksum: f12d3fbc2d49396ec523170828a5c9a89bc7740eb7b205f8d8553af18629d936474c1ce55b70c7839aa239a11252e16fd1c3fc955b966b81c9dec00155df4f85 +"smol-toml@npm:^1.4.2, smol-toml@npm:^1.5.2": + version: 1.5.2 + resolution: "smol-toml@npm:1.5.2" + checksum: 75b7e8482151cbe48be094de205631502d5694c2a7d968446799e8b988b4105bd6efd3b6a986baa40d9e9b47cbb2daada21a302901a618793aabd35a670f195e languageName: node linkType: hard @@ -19271,10 +19223,10 @@ __metadata: languageName: node linkType: hard -"strip-json-comments@npm:5.0.2": - version: 5.0.2 - resolution: "strip-json-comments@npm:5.0.2" - checksum: 986064b73898edc77113cd6147b32f36e299869f3675ed81c3166492a6d8f02d918a492604d1982dab40ca727a86969cb91aa44d6632626f8d7c3c6ead1216bb +"strip-json-comments@npm:5.0.3": + version: 5.0.3 + resolution: "strip-json-comments@npm:5.0.3" + checksum: 3ccbf26f278220f785e4b71f8a719a6a063d72558cc63cb450924254af258a4f4c008b8c9b055373a680dc7bd525be9e543ad742c177f8a7667e0b726258e0e4 languageName: node linkType: hard @@ -19639,7 +19591,7 @@ __metadata: languageName: node linkType: hard -"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.13, 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": version: 0.2.15 resolution: "tinyglobby@npm:0.2.15" dependencies: @@ -19970,10 +19922,10 @@ __metadata: version: 0.0.0-use.local resolution: "typescript-eslint@workspace:packages/typescript-eslint" dependencies: - "@typescript-eslint/eslint-plugin": 8.47.0 - "@typescript-eslint/parser": 8.47.0 - "@typescript-eslint/typescript-estree": 8.47.0 - "@typescript-eslint/utils": 8.47.0 + "@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 "@vitest/coverage-v8": ^3.1.3 eslint: "*" rimraf: "*" @@ -20307,15 +20259,6 @@ __metadata: languageName: node linkType: hard -"validate-npm-package-name@npm:^5.0.0": - version: 5.0.0 - resolution: "validate-npm-package-name@npm:5.0.0" - dependencies: - builtins: ^5.0.0 - checksum: 5342a994986199b3c28e53a8452a14b2bb5085727691ea7aa0d284a6606b127c371e0925ae99b3f1ef7cc7d2c9de75f52eb61a3d1cc45e39bca1e3a9444cbb4e - languageName: node - linkType: hard - "value-equal@npm:^1.0.1": version: 1.0.1 resolution: "value-equal@npm:1.0.1" @@ -20376,9 +20319,9 @@ __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" +"vite@npm:7.2.4": + version: 7.2.4 + resolution: "vite@npm:7.2.4" dependencies: esbuild: ^0.25.0 fdir: ^6.5.0 @@ -20427,30 +20370,30 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 4be31af222b94aeaf627443b37e13239ca81bedcf29fb952580272098b966314a5136edf65fbd5b66bbcc84cc1c48403fcadb79d858da4bad455fc9a0da263b7 + checksum: 5a8296eb9612876a5c783af1410574c524bcda5b8df5a77e4b0ff811f5caee8074cb806e775a91755128cf997dc3192de26b109c340a851050a5a5368bd48aea languageName: node linkType: hard -"vite@npm:^6.3.5": - version: 6.4.1 - resolution: "vite@npm:6.4.1" +"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.4.4 + fdir: ^6.5.0 fsevents: ~2.3.3 - picomatch: ^4.0.2 - postcss: ^8.5.3 - rollup: ^4.34.9 - tinyglobby: ^0.2.13 + picomatch: ^4.0.3 + postcss: ^8.5.6 + rollup: ^4.43.0 + tinyglobby: ^0.2.15 peerDependencies: - "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 + "@types/node": ^20.19.0 || >=22.12.0 jiti: ">=1.21.0" - less: "*" + less: ^4.0.0 lightningcss: ^1.21.0 - sass: "*" - sass-embedded: "*" - stylus: "*" - sugarss: "*" + 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 @@ -20482,7 +20425,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 7a939dbd6569ba829a7c21a18f8eca395a3a13cb93ce0fec02e8aa462e127a8daac81d00f684086648d905786056bba1ad931f51d88f06835d3b972bc9fbddda + checksum: 4be31af222b94aeaf627443b37e13239ca81bedcf29fb952580272098b966314a5136edf65fbd5b66bbcc84cc1c48403fcadb79d858da4bad455fc9a0da263b7 languageName: node linkType: hard