eslint-plugin-th-rules 3.3.2 → 3.3.3

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/README.md CHANGED
@@ -172,8 +172,9 @@ Do not edit below this line.
172
172
  | [no-comments](docs/rules/no-comments.md) | Disallow comments except for specified allowed patterns. | ✅ ⚛️ 🟦 🎲 | 🔧 |
173
173
  | [no-default-export](docs/rules/no-default-export.md) | Convert unnamed default exports to named default exports based on the file name. | ✅ ⚛️ 🟦 🎲 | 🔧 |
174
174
  | [no-destructuring](docs/rules/no-destructuring.md) | Disallow destructuring that does not meet certain conditions. | ✅ ⚛️ 🟦 🎲 | |
175
+ | [no-explicit-nil-check](docs/rules/no-explicit-nil-check.md) | Disallow implicit truthy/falsy checks anywhere. Require explicit _.isNil(value). | ✅ ⚛️ 🟦 🎲 | 🔧 |
175
176
  | [no-explicit-nil-compare](docs/rules/no-explicit-nil-compare.md) | Disallow direct comparisons to null or undefined. Use _.isNull(x) / _.isUndefined(x) instead. | ✅ ⚛️ 🟦 🎲 | 🔧 |
176
- | [prefer-is-empty](docs/rules/prefer-is-empty.md) | Require _.isEmpty instead of length comparisons or !x.length checks. | ✅ ⚛️ 🟦 🎲 | 🔧 |
177
+ | [prefer-is-empty](docs/rules/prefer-is-empty.md) | Require _.isEmpty instead of length comparisons or boolean checks on .length. | ✅ ⚛️ 🟦 🎲 | 🔧 |
177
178
  | [schemas-in-schemas-file](docs/rules/schemas-in-schemas-file.md) | Require Zod schema declarations to be placed in a .schemas.ts file. | ✅ ⚛️ 🟦 🎲 | |
178
179
  | [top-level-functions](docs/rules/top-level-functions.md) | Require all top-level functions to be named regular functions. | ✅ ⚛️ 🟦 🎲 | 🔧 |
179
180
  | [types-in-dts](docs/rules/types-in-dts.md) | Require TypeScript type declarations (type/interface/enum) to be placed in .d.ts files. | ✅ ⚛️ 🟦 🎲 | |
package/dist/plugin.d.ts CHANGED
@@ -20,7 +20,7 @@ export declare const rules: {
20
20
  'no-explicit-nil-compare': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useIsNull" | "useIsUndefined", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
21
21
  name: string;
22
22
  };
23
- 'no-explicit-nil-check': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useIsNil", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
23
+ 'prefer-explicit-nil-check': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useIsNil", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
24
24
  name: string;
25
25
  };
26
26
  'prefer-is-empty': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useIsEmpty" | "useIsEmptyUnary" | "useIsEmptyBoolean", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
@@ -66,7 +66,7 @@ declare const plugin: {
66
66
  'no-explicit-nil-compare': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useIsNull" | "useIsUndefined", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
67
67
  name: string;
68
68
  };
69
- 'no-explicit-nil-check': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useIsNil", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
69
+ 'prefer-explicit-nil-check': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useIsNil", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
70
70
  name: string;
71
71
  };
72
72
  'prefer-is-empty': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useIsEmpty" | "useIsEmptyUnary" | "useIsEmptyBoolean", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
package/dist/plugin.js CHANGED
@@ -14,7 +14,7 @@ export const rules = {
14
14
  'no-default-export': noDefaultExport,
15
15
  'no-destructuring': noDestructuring,
16
16
  'no-explicit-nil-compare': noExplicitNilCompare,
17
- 'no-explicit-nil-check': preferExplicitNilCheck,
17
+ 'prefer-explicit-nil-check': preferExplicitNilCheck,
18
18
  'prefer-is-empty': preferIsEmpty,
19
19
  'schemas-in-schemas-file': schemasInSchemasFile,
20
20
  'top-level-functions': topLevelFunctions,
@@ -1 +1 @@
1
- {"version":3,"file":"prefer-explicit-nil-check.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-explicit-nil-check.ts"],"names":[],"mappings":"AAIA,OAAO,EAAkB,WAAW,EAAiB,MAAM,0BAA0B,CAAC;AAWtF,QAAA,MAAM,sBAAsB;;CA4X1B,CAAC;AAEH,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"prefer-explicit-nil-check.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-explicit-nil-check.ts"],"names":[],"mappings":"AAIA,OAAO,EAAkB,WAAW,EAAiB,MAAM,0BAA0B,CAAC;AAWtF,QAAA,MAAM,sBAAsB;;CA0Z1B,CAAC;AAEH,eAAe,sBAAsB,CAAC"}
@@ -65,6 +65,27 @@ const preferExplicitNilCheck = createRule({
65
65
  function isBooleanLikeFlag(flags) {
66
66
  return (flags & ts.TypeFlags.BooleanLike) !== 0;
67
67
  }
68
+ function isAnyOrUnknownFlag(flags) {
69
+ return (flags & ts.TypeFlags.Any) !== 0 || (flags & ts.TypeFlags.Unknown) !== 0;
70
+ }
71
+ /**
72
+ * Skip when the type is `any` or `unknown` (including union constituents),
73
+ * because we can't safely decide whether to prefer isNil/isEmpty without
74
+ * risking semantic changes.
75
+ */
76
+ function isAnyOrUnknownByTS(node) {
77
+ const type = getTsType(node);
78
+ if (_.isNil(type))
79
+ return false;
80
+ if (!type.isUnion()) {
81
+ return isAnyOrUnknownFlag(type.getFlags());
82
+ }
83
+ for (const t of type.types) {
84
+ if (isAnyOrUnknownFlag(t.getFlags()))
85
+ return true;
86
+ }
87
+ return false;
88
+ }
68
89
  /**
69
90
  * Returns true iff the expression type is effectively:
70
91
  * string | null | undefined
@@ -176,6 +197,8 @@ const preferExplicitNilCheck = createRule({
176
197
  });
177
198
  }
178
199
  function transformTruthy(node) {
200
+ if (isAnyOrUnknownByTS(node))
201
+ return;
179
202
  if (isNumberByTS(node))
180
203
  return;
181
204
  const text = context.sourceCode.getText(node);
@@ -187,6 +210,8 @@ const preferExplicitNilCheck = createRule({
187
210
  }
188
211
  function transformFalsyUnary(node) {
189
212
  const arg = node.argument;
213
+ if (isAnyOrUnknownByTS(arg))
214
+ return;
190
215
  if (isNumberByTS(arg))
191
216
  return;
192
217
  const text = context.sourceCode.getText(arg);
@@ -277,6 +302,8 @@ const preferExplicitNilCheck = createRule({
277
302
  return;
278
303
  }
279
304
  if (isImplicitOperand(arg)) {
305
+ if (isAnyOrUnknownByTS(arg))
306
+ return;
280
307
  if (isBooleanByTS(arg))
281
308
  return;
282
309
  if (isNumberByTS(arg))
@@ -293,6 +320,8 @@ const preferExplicitNilCheck = createRule({
293
320
  }
294
321
  default: {
295
322
  if (mode === 'test' && isImplicitOperand(node)) {
323
+ if (isAnyOrUnknownByTS(node))
324
+ return;
296
325
  if (isBooleanByTS(node))
297
326
  return;
298
327
  if (isNumberByTS(node))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-th-rules",
3
- "version": "3.3.2",
3
+ "version": "3.3.3",
4
4
  "description": "A List of custom ESLint rules created by Tomer Horowitz",
5
5
  "keywords": [
6
6
  "eslint",