@typescript-eslint/eslint-plugin 8.68.1-alpha.8 → 8.69.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,26 @@
1
+ ## 8.69.0 (2026-08-31)
2
+
3
+ ### 🚀 Features
4
+
5
+ - **eslint-plugin:** [no-misused-promises] add flagUnions option for checkConditionals ([#12603](https://github.com/typescript-eslint/typescript-eslint/pull/12603))
6
+
7
+ ### 🩹 Fixes
8
+
9
+ - **eslint-plugin:** [no-meaningless-void-operator] report void on non-call expressions ([#12727](https://github.com/typescript-eslint/typescript-eslint/pull/12727))
10
+ - **eslint-plugin:** [unified-signatures] compare type parameters by constraint instead of name ([#12741](https://github.com/typescript-eslint/typescript-eslint/pull/12741))
11
+ - **eslint-plugin:** [no-mixed-enums] use scope analysis instead of type checking for merged namespaces ([#12731](https://github.com/typescript-eslint/typescript-eslint/pull/12731))
12
+
13
+ ### ❤️ Thank You
14
+
15
+ - Abdu Alim Arlikhozhaev @Arlikhozhaev
16
+ - Evyatar Daud @StyleShit
17
+ - Josh Goldberg ✨
18
+ - wonbeanie @wonbeanie
19
+
20
+ See [GitHub Releases](https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.69.0) for more information.
21
+
22
+ You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website.
23
+
1
24
  ## 8.68.0 (2026-08-24)
2
25
 
3
26
  ### 🚀 Features
package/dist/index.d.ts CHANGED
@@ -855,7 +855,7 @@ declare const _default: {
855
855
  }], import("../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
856
856
  name: string;
857
857
  };
858
- 'no-meaningless-void-operator': import("@typescript-eslint/utils/ts-eslint").RuleModule<"meaninglessVoidOperator" | "removeVoid", import("./rules/no-meaningless-void-operator").Options, import("../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
858
+ 'no-meaningless-void-operator': import("@typescript-eslint/utils/ts-eslint").RuleModule<"meaninglessVoidOnNonCall" | "meaninglessVoidOperator" | "removeVoid", import("./rules/no-meaningless-void-operator").Options, import("../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
859
859
  name: string;
860
860
  };
861
861
  'no-misused-new': import("@typescript-eslint/utils/ts-eslint").RuleModule<"errorMessageClass" | "errorMessageInterface", [], import("../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
@@ -878,7 +878,7 @@ declare const _default: {
878
878
  }], import("../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
879
879
  name: string;
880
880
  };
881
- 'no-meaningless-void-operator': TSESLint.RuleModule<"meaninglessVoidOperator" | "removeVoid", import("./rules/no-meaningless-void-operator").Options, import("../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
881
+ 'no-meaningless-void-operator': TSESLint.RuleModule<"meaninglessVoidOnNonCall" | "meaninglessVoidOperator" | "removeVoid", import("./rules/no-meaningless-void-operator").Options, import("../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
882
882
  name: string;
883
883
  };
884
884
  'no-misused-new': TSESLint.RuleModule<"errorMessageClass" | "errorMessageInterface", [], import("../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
@@ -180,7 +180,7 @@ declare const rules: {
180
180
  }], import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
181
181
  name: string;
182
182
  };
183
- 'no-meaningless-void-operator': import("@typescript-eslint/utils/ts-eslint").RuleModule<"meaninglessVoidOperator" | "removeVoid", import("./no-meaningless-void-operator").Options, import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
183
+ 'no-meaningless-void-operator': import("@typescript-eslint/utils/ts-eslint").RuleModule<"meaninglessVoidOnNonCall" | "meaninglessVoidOperator" | "removeVoid", import("./no-meaningless-void-operator").Options, import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
184
184
  name: string;
185
185
  };
186
186
  'no-misused-new': import("@typescript-eslint/utils/ts-eslint").RuleModule<"errorMessageClass" | "errorMessageInterface", [], import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
@@ -4,7 +4,7 @@ export type Options = [
4
4
  checkNever: boolean;
5
5
  }
6
6
  ];
7
- declare const _default: TSESLint.RuleModule<"meaninglessVoidOperator" | "removeVoid", Options, import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
7
+ declare const _default: TSESLint.RuleModule<"meaninglessVoidOnNonCall" | "meaninglessVoidOperator" | "removeVoid", Options, import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
8
8
  name: string;
9
9
  };
10
10
  export default _default;
@@ -49,6 +49,7 @@ exports.default = (0, util_1.createRule)({
49
49
  fixable: 'code',
50
50
  hasSuggestions: true,
51
51
  messages: {
52
+ meaninglessVoidOnNonCall: "void operator is useless here; it should only discard a call's return value",
52
53
  meaninglessVoidOperator: "void operator shouldn't be used on {{type}}; it should convey that a return value is being ignored",
53
54
  removeVoid: "Remove 'void'",
54
55
  },
@@ -59,7 +60,7 @@ exports.default = (0, util_1.createRule)({
59
60
  properties: {
60
61
  checkNever: {
61
62
  type: 'boolean',
62
- description: 'Whether to suggest removing `void` when the argument has type `never`.',
63
+ description: "Whether to suggest removing `void` when a call's return type is `never`.",
63
64
  },
64
65
  },
65
66
  },
@@ -77,6 +78,27 @@ exports.default = (0, util_1.createRule)({
77
78
  context.sourceCode.getTokens(node)[1].range[0],
78
79
  ]);
79
80
  };
81
+ const inner = unwrapVoidArgument(node.argument);
82
+ if (inner.type !== utils_1.AST_NODE_TYPES.CallExpression) {
83
+ // `void 0` is a common undefined idiom, not a discarded call.
84
+ if (inner.type === utils_1.AST_NODE_TYPES.Literal && inner.value === 0) {
85
+ return;
86
+ }
87
+ const tsArgument = services.esTreeNodeToTSNodeMap.get(node.argument);
88
+ const argType = services.getTypeAtLocation(node.argument);
89
+ // Allow `void promiseValue` so this rule does not fight no-floating-promises.
90
+ if (tsutils.isThenableType(checker, tsArgument, argType)) {
91
+ return;
92
+ }
93
+ context.report({
94
+ node,
95
+ messageId: 'meaninglessVoidOnNonCall',
96
+ fix: node.parent.type === utils_1.AST_NODE_TYPES.ExpressionStatement
97
+ ? fix
98
+ : undefined,
99
+ });
100
+ return;
101
+ }
80
102
  const argType = services.getTypeAtLocation(node.argument);
81
103
  const unionParts = tsutils.unionConstituents(argType);
82
104
  if (unionParts.every(part => tsutils.isTypeFlagSet(part, ts.TypeFlags.Void | ts.TypeFlags.Undefined))) {
@@ -100,4 +122,23 @@ exports.default = (0, util_1.createRule)({
100
122
  };
101
123
  },
102
124
  });
125
+ function unwrapVoidArgument(node) {
126
+ let current = node;
127
+ while (true) {
128
+ switch (current.type) {
129
+ case utils_1.AST_NODE_TYPES.ChainExpression:
130
+ case utils_1.AST_NODE_TYPES.TSAsExpression:
131
+ case utils_1.AST_NODE_TYPES.TSNonNullExpression:
132
+ case utils_1.AST_NODE_TYPES.TSSatisfiesExpression:
133
+ case utils_1.AST_NODE_TYPES.TSTypeAssertion:
134
+ current = current.expression;
135
+ continue;
136
+ case utils_1.AST_NODE_TYPES.SequenceExpression:
137
+ current = (0, util_1.nullThrows)(current.expressions.at(-1), 'Expected SequenceExpression to have at least one expression');
138
+ continue;
139
+ default:
140
+ return current;
141
+ }
142
+ }
143
+ }
103
144
  //# sourceMappingURL=no-meaningless-void-operator.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typescript-eslint/eslint-plugin",
3
- "version": "8.68.1-alpha.8",
3
+ "version": "8.69.0",
4
4
  "description": "TypeScript plugin for ESLint",
5
5
  "files": [
6
6
  "dist",
@@ -47,10 +47,10 @@
47
47
  ],
48
48
  "dependencies": {
49
49
  "@eslint-community/regexpp": "^4.12.2",
50
- "@typescript-eslint/scope-manager": "8.68.1-alpha.8",
51
- "@typescript-eslint/type-utils": "8.68.1-alpha.8",
52
- "@typescript-eslint/utils": "8.68.1-alpha.8",
53
- "@typescript-eslint/visitor-keys": "8.68.1-alpha.8",
50
+ "@typescript-eslint/scope-manager": "8.69.0",
51
+ "@typescript-eslint/type-utils": "8.69.0",
52
+ "@typescript-eslint/utils": "8.69.0",
53
+ "@typescript-eslint/visitor-keys": "8.69.0",
54
54
  "ignore": "^7.0.5",
55
55
  "natural-compare": "^1.4.0",
56
56
  "ts-api-utils": "^2.5.0"
@@ -60,8 +60,8 @@
60
60
  "@types/mdast": "^4.0.4",
61
61
  "@types/natural-compare": "^1.4.3",
62
62
  "@types/react": "^18.3.21",
63
- "@typescript-eslint/rule-schema-to-typescript-types": "8.68.1-alpha.8",
64
- "@typescript-eslint/rule-tester": "8.68.1-alpha.8",
63
+ "@typescript-eslint/rule-schema-to-typescript-types": "8.69.0",
64
+ "@typescript-eslint/rule-tester": "8.69.0",
65
65
  "@typescript/native": "npm:typescript@^7.0.2",
66
66
  "@vitest/coverage-v8": "^4.0.18",
67
67
  "ajv": "^6.12.6",
@@ -81,7 +81,7 @@
81
81
  "vitest": "^4.0.18"
82
82
  },
83
83
  "peerDependencies": {
84
- "@typescript-eslint/parser": "^8.68.1-alpha.8",
84
+ "@typescript-eslint/parser": "^8.69.0",
85
85
  "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
86
86
  "typescript": ">=4.8.4 <6.1.0"
87
87
  },