@typescript-eslint/eslint-plugin 8.53.2-alpha.4 → 8.53.2-alpha.6
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.
|
@@ -281,8 +281,17 @@ exports.default = (0, util_1.createRule)({
|
|
|
281
281
|
return;
|
|
282
282
|
}
|
|
283
283
|
const originalNode = services.esTreeNodeToTSNodeMap.get(node);
|
|
284
|
-
const
|
|
285
|
-
|
|
284
|
+
const constrainedType = (0, util_1.getConstrainedTypeAtLocation)(services, node.expression);
|
|
285
|
+
const actualType = services.getTypeAtLocation(node.expression);
|
|
286
|
+
// Check both the constrained type and the actual type.
|
|
287
|
+
// If either is nullable, we should not report the assertion as unnecessary.
|
|
288
|
+
// This handles cases like generic constraints with `any` where the
|
|
289
|
+
// constrained type is `any` (nullable) but the actual type might be
|
|
290
|
+
// a type parameter that TypeScript treats nominally.
|
|
291
|
+
// See: https://github.com/typescript-eslint/typescript-eslint/issues/11559
|
|
292
|
+
const constrainedTypeIsNullable = (0, util_1.isNullableType)(constrainedType);
|
|
293
|
+
const actualTypeIsNullable = (0, util_1.isNullableType)(actualType);
|
|
294
|
+
if (!constrainedTypeIsNullable && !actualTypeIsNullable) {
|
|
286
295
|
if (node.expression.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
287
296
|
isPossiblyUsedBeforeAssigned(node.expression)) {
|
|
288
297
|
return;
|
|
@@ -296,17 +305,25 @@ exports.default = (0, util_1.createRule)({
|
|
|
296
305
|
else {
|
|
297
306
|
// we know it's a nullable type
|
|
298
307
|
// so figure out if the variable is used in a place that accepts nullable types
|
|
308
|
+
// If the constrained type differs from the actual type (e.g., when dealing
|
|
309
|
+
// with unresolved generic type parameters), we should not report the assertion
|
|
310
|
+
// as contextually unnecessary. TypeScript may still require the assertion
|
|
311
|
+
// even if the constraint is nullable (like `any`).
|
|
312
|
+
// See: https://github.com/typescript-eslint/typescript-eslint/issues/11559
|
|
313
|
+
if (constrainedType !== actualType) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
299
316
|
const contextualType = (0, util_1.getContextualType)(checker, originalNode);
|
|
300
317
|
if (contextualType) {
|
|
301
|
-
if ((0, util_1.isTypeFlagSet)(
|
|
318
|
+
if ((0, util_1.isTypeFlagSet)(constrainedType, ts.TypeFlags.Unknown) &&
|
|
302
319
|
!(0, util_1.isTypeFlagSet)(contextualType, ts.TypeFlags.Unknown)) {
|
|
303
320
|
return;
|
|
304
321
|
}
|
|
305
322
|
// in strict mode you can't assign null to undefined, so we have to make sure that
|
|
306
323
|
// the two types share a nullable type
|
|
307
|
-
const typeIncludesUndefined = (0, util_1.isTypeFlagSet)(
|
|
308
|
-
const typeIncludesNull = (0, util_1.isTypeFlagSet)(
|
|
309
|
-
const typeIncludesVoid = (0, util_1.isTypeFlagSet)(
|
|
324
|
+
const typeIncludesUndefined = (0, util_1.isTypeFlagSet)(constrainedType, ts.TypeFlags.Undefined);
|
|
325
|
+
const typeIncludesNull = (0, util_1.isTypeFlagSet)(constrainedType, ts.TypeFlags.Null);
|
|
326
|
+
const typeIncludesVoid = (0, util_1.isTypeFlagSet)(constrainedType, ts.TypeFlags.Void);
|
|
310
327
|
const contextualTypeIncludesUndefined = (0, util_1.isTypeFlagSet)(contextualType, ts.TypeFlags.Undefined);
|
|
311
328
|
const contextualTypeIncludesNull = (0, util_1.isTypeFlagSet)(contextualType, ts.TypeFlags.Null);
|
|
312
329
|
const contextualTypeIncludesVoid = (0, util_1.isTypeFlagSet)(contextualType, ts.TypeFlags.Void);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typescript-eslint/eslint-plugin",
|
|
3
|
-
"version": "8.53.2-alpha.
|
|
3
|
+
"version": "8.53.2-alpha.6",
|
|
4
4
|
"description": "TypeScript plugin for ESLint",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -59,10 +59,10 @@
|
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@eslint-community/regexpp": "^4.12.2",
|
|
62
|
-
"@typescript-eslint/scope-manager": "8.53.2-alpha.
|
|
63
|
-
"@typescript-eslint/type-utils": "8.53.2-alpha.
|
|
64
|
-
"@typescript-eslint/utils": "8.53.2-alpha.
|
|
65
|
-
"@typescript-eslint/visitor-keys": "8.53.2-alpha.
|
|
62
|
+
"@typescript-eslint/scope-manager": "8.53.2-alpha.6",
|
|
63
|
+
"@typescript-eslint/type-utils": "8.53.2-alpha.6",
|
|
64
|
+
"@typescript-eslint/utils": "8.53.2-alpha.6",
|
|
65
|
+
"@typescript-eslint/visitor-keys": "8.53.2-alpha.6",
|
|
66
66
|
"ignore": "^7.0.5",
|
|
67
67
|
"natural-compare": "^1.4.0",
|
|
68
68
|
"ts-api-utils": "^2.4.0"
|
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/mdast": "^4.0.4",
|
|
72
72
|
"@types/natural-compare": "*",
|
|
73
|
-
"@typescript-eslint/rule-schema-to-typescript-types": "8.53.2-alpha.
|
|
74
|
-
"@typescript-eslint/rule-tester": "8.53.2-alpha.
|
|
73
|
+
"@typescript-eslint/rule-schema-to-typescript-types": "8.53.2-alpha.6",
|
|
74
|
+
"@typescript-eslint/rule-tester": "8.53.2-alpha.6",
|
|
75
75
|
"@vitest/coverage-v8": "^3.2.4",
|
|
76
76
|
"ajv": "^6.12.6",
|
|
77
77
|
"eslint": "*",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"mdast-util-from-markdown": "^2.0.2",
|
|
82
82
|
"mdast-util-mdx": "^3.0.0",
|
|
83
83
|
"micromark-extension-mdxjs": "^3.0.0",
|
|
84
|
-
"prettier": "3.
|
|
84
|
+
"prettier": "3.8.0",
|
|
85
85
|
"rimraf": "*",
|
|
86
86
|
"title-case": "^4.3.2",
|
|
87
87
|
"tsx": "*",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"vitest": "^3.2.4"
|
|
91
91
|
},
|
|
92
92
|
"peerDependencies": {
|
|
93
|
-
"@typescript-eslint/parser": "^8.53.2-alpha.
|
|
93
|
+
"@typescript-eslint/parser": "^8.53.2-alpha.6",
|
|
94
94
|
"eslint": "^8.57.0 || ^9.0.0",
|
|
95
95
|
"typescript": ">=4.8.4 <6.0.0"
|
|
96
96
|
},
|