eslint-plugin-th-rules 3.4.0 → 3.4.2

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.
@@ -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;;CA0Z1B,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;;CA0d1B,CAAC;AAEH,eAAe,sBAAsB,CAAC"}
@@ -46,12 +46,33 @@ const preferExplicitNilCheck = createRule({
46
46
  return node.expression;
47
47
  return node;
48
48
  }
49
+ function getTypeFromSymbolAnnotation(symbol) {
50
+ const decl = symbol.valueDeclaration ?? symbol.declarations?.[0];
51
+ if (_.isNil(decl))
52
+ return null;
53
+ if ('type' in decl) {
54
+ const typeNode = decl.type;
55
+ if (!_.isNil(typeNode)) {
56
+ return checker.getTypeFromTypeNode(typeNode);
57
+ }
58
+ }
59
+ return null;
60
+ }
49
61
  function getTsType(node) {
50
62
  const unwrapped = unwrapChainExpression(node);
51
63
  const tsNode = services.esTreeNodeToTSNodeMap.get(unwrapped);
52
64
  if (_.isNil(tsNode))
53
65
  return null;
54
- return checker.getTypeAtLocation(tsNode);
66
+ let type;
67
+ if (unwrapped.type === AST_NODE_TYPES.Identifier) {
68
+ const symbol = checker.getSymbolAtLocation(tsNode);
69
+ const annotated = _.isNil(symbol) ? null : getTypeFromSymbolAnnotation(symbol);
70
+ type = annotated ?? checker.getTypeAtLocation(tsNode);
71
+ }
72
+ else {
73
+ type = checker.getTypeAtLocation(tsNode);
74
+ }
75
+ return checker.getWidenedType(type);
55
76
  }
56
77
  function isNullableFlag(flags) {
57
78
  return (flags & ts.TypeFlags.Null) !== 0 || (flags & ts.TypeFlags.Undefined) !== 0;
@@ -86,6 +107,38 @@ const preferExplicitNilCheck = createRule({
86
107
  }
87
108
  return false;
88
109
  }
110
+ /**
111
+ * Returns true when the type is a union that includes boolean-like AND also
112
+ * includes some other non-nullish, non-boolean-like constituent.
113
+ *
114
+ * Example: string | object | null | boolean | number
115
+ *
116
+ * In these cases we avoid rewriting `if (x)` / `if (!x)` because the intent
117
+ * may be genuine boolean gating (or semantic-preserving rewrite isn't clear).
118
+ */
119
+ function isPartialBooleanUnionByTS(node) {
120
+ const type = getTsType(node);
121
+ if (_.isNil(type))
122
+ return false;
123
+ if (!type.isUnion())
124
+ return false;
125
+ let sawBoolean = false;
126
+ let sawOtherNonNullish = false;
127
+ for (const t of type.types) {
128
+ const flags = t.getFlags();
129
+ if (isNullableFlag(flags))
130
+ continue;
131
+ if (isBooleanLikeFlag(flags)) {
132
+ sawBoolean = true;
133
+ }
134
+ else {
135
+ sawOtherNonNullish = true;
136
+ }
137
+ if (sawBoolean && sawOtherNonNullish)
138
+ return true;
139
+ }
140
+ return false;
141
+ }
89
142
  /**
90
143
  * Returns true iff the expression type is effectively:
91
144
  * string | null | undefined
@@ -201,6 +254,8 @@ const preferExplicitNilCheck = createRule({
201
254
  return;
202
255
  if (isNumberByTS(node))
203
256
  return;
257
+ if (isPartialBooleanUnionByTS(node))
258
+ return;
204
259
  const text = context.sourceCode.getText(node);
205
260
  if (isStringByTS(node)) {
206
261
  reportFull(node, `!${LODASH_IDENT}.isEmpty(${text})`);
@@ -214,6 +269,8 @@ const preferExplicitNilCheck = createRule({
214
269
  return;
215
270
  if (isNumberByTS(arg))
216
271
  return;
272
+ if (isPartialBooleanUnionByTS(arg))
273
+ return;
217
274
  const text = context.sourceCode.getText(arg);
218
275
  if (isStringByTS(arg)) {
219
276
  reportFull(node, `${LODASH_IDENT}.isEmpty(${text})`);
@@ -306,6 +363,8 @@ const preferExplicitNilCheck = createRule({
306
363
  return;
307
364
  if (isBooleanByTS(arg))
308
365
  return;
366
+ if (isPartialBooleanUnionByTS(arg))
367
+ return;
309
368
  if (isNumberByTS(arg))
310
369
  return;
311
370
  transformFalsyUnary(node);
@@ -324,6 +383,8 @@ const preferExplicitNilCheck = createRule({
324
383
  return;
325
384
  if (isBooleanByTS(node))
326
385
  return;
386
+ if (isPartialBooleanUnionByTS(node))
387
+ return;
327
388
  if (isNumberByTS(node))
328
389
  return;
329
390
  transformTruthy(node);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-th-rules",
3
- "version": "3.4.0",
3
+ "version": "3.4.2",
4
4
  "description": "A List of custom ESLint rules created by Tomer Horowitz",
5
5
  "keywords": [
6
6
  "eslint",