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
|
|
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
|
-
'
|
|
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
|
-
'
|
|
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
|
-
'
|
|
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;;
|
|
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))
|