@typescript-eslint/eslint-plugin 8.70.1-alpha.18 → 8.70.1-alpha.19

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.
@@ -55,6 +55,15 @@ function isPossiblyNullish(type) {
55
55
  .unionConstituents(type)
56
56
  .some(t => isNullishType(t) || (0, util_1.isTypeFlagSet)(t, ts.TypeFlags.Void));
57
57
  }
58
+ /**
59
+ * Note that this differs from {@link isNullableType} in that it doesn't consider
60
+ * `any` or `unknown` to be nullable.
61
+ */
62
+ function isPossiblyNonNullish(type) {
63
+ return tsutils
64
+ .unionConstituents(type)
65
+ .some(t => !isNullishType(t) && !(0, util_1.isTypeFlagSet)(t, ts.TypeFlags.Void));
66
+ }
58
67
  function toStaticValue(type) {
59
68
  // type.isLiteral() only covers numbers/bigints and strings, hence the rest of the branches.
60
69
  if (tsutils.isBooleanLiteralType(type)) {
@@ -262,11 +271,48 @@ exports.default = (0, util_1.createRule)({
262
271
  const propertyType = objectType
263
272
  .getProperties()
264
273
  .find(prop => prop.name === propertyName);
265
- if (propertyType &&
266
- tsutils.isSymbolFlagSet(propertyType, ts.SymbolFlags.Optional)) {
267
- return true;
274
+ return (propertyType != null &&
275
+ tsutils.isSymbolFlagSet(propertyType, ts.SymbolFlags.Optional));
276
+ }
277
+ /**
278
+ * Obtains the property types of the computed member expression
279
+ * @param node The member expression
280
+ * @returns The property types, unless the node isn't computed.
281
+ */
282
+ function getComputedMemberPropertyTypes(node) {
283
+ if (!node.computed) {
284
+ return undefined;
285
+ }
286
+ const objectType = (0, util_1.getConstrainedTypeAtLocation)(services, node.object);
287
+ const propertyType = (0, util_1.getConstrainedTypeAtLocation)(services, node.property);
288
+ const propertyTypes = [];
289
+ for (const keyType of tsutils.unionConstituents(propertyType)) {
290
+ if (!keyType.isStringLiteral() && !keyType.isNumberLiteral()) {
291
+ return undefined;
292
+ }
293
+ const selectedType = (0, util_1.getTypeOfPropertyOfName)(checker, objectType, String(keyType.value));
294
+ if (!selectedType) {
295
+ return undefined;
296
+ }
297
+ propertyTypes.push(selectedType);
268
298
  }
269
- return false;
299
+ return propertyTypes;
300
+ }
301
+ /**
302
+ * Verify if the node may have non-nullish properties
303
+ * @param node The node to verify
304
+ * @returns If it may have non-nullish properties, unless the node isn't a
305
+ * MemberExpression
306
+ */
307
+ function hasPossiblyNonNullishComputedMemberProperty(node) {
308
+ if (node.type !== utils_1.AST_NODE_TYPES.MemberExpression) {
309
+ return false;
310
+ }
311
+ const propertyTypes = getComputedMemberPropertyTypes(node);
312
+ if (propertyTypes == null) {
313
+ return false;
314
+ }
315
+ return propertyTypes.some(isPossiblyNonNullish);
270
316
  }
271
317
  /**
272
318
  * Checks if a conditional node is necessary:
@@ -344,7 +390,8 @@ exports.default = (0, util_1.createRule)({
344
390
  messageId = 'neverNullish';
345
391
  }
346
392
  }
347
- else if (isAlwaysNullish(type)) {
393
+ else if (isAlwaysNullish(type) &&
394
+ !hasPossiblyNonNullishComputedMemberProperty(node)) {
348
395
  messageId = 'alwaysNullish';
349
396
  }
350
397
  if (messageId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typescript-eslint/eslint-plugin",
3
- "version": "8.70.1-alpha.18",
3
+ "version": "8.70.1-alpha.19",
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.70.1-alpha.18",
51
- "@typescript-eslint/type-utils": "8.70.1-alpha.18",
52
- "@typescript-eslint/utils": "8.70.1-alpha.18",
53
- "@typescript-eslint/visitor-keys": "8.70.1-alpha.18",
50
+ "@typescript-eslint/scope-manager": "8.70.1-alpha.19",
51
+ "@typescript-eslint/type-utils": "8.70.1-alpha.19",
52
+ "@typescript-eslint/utils": "8.70.1-alpha.19",
53
+ "@typescript-eslint/visitor-keys": "8.70.1-alpha.19",
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.70.1-alpha.18",
64
- "@typescript-eslint/rule-tester": "8.70.1-alpha.18",
63
+ "@typescript-eslint/rule-schema-to-typescript-types": "8.70.1-alpha.19",
64
+ "@typescript-eslint/rule-tester": "8.70.1-alpha.19",
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.70.1-alpha.18",
84
+ "@typescript-eslint/parser": "^8.70.1-alpha.19",
85
85
  "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
86
86
  "typescript": ">=4.8.4 <6.1.0"
87
87
  },