Skip to content

fix(eslint-plugin): [no-uncalled-signals] properly handle statements with unary operators#2926

Merged
JamesHenry merged 2 commits into
angular-eslint:mainfrom
BEGEMOT9I:fix/no-uncalled-signals-unary-operator
Mar 17, 2026
Merged

fix(eslint-plugin): [no-uncalled-signals] properly handle statements with unary operators#2926
JamesHenry merged 2 commits into
angular-eslint:mainfrom
BEGEMOT9I:fix/no-uncalled-signals-unary-operator

Conversation

@BEGEMOT9I

Copy link
Copy Markdown
Contributor

Previously, not all operations with unary operators were handled correctly. For example, it was possible to return an incorrectly handled signal from a method in a component:

type User = {
  id: string;
}

@Component({})
class TestComponent {
  user = signal<User | undefined>();

  hasNoUser = computed<boolean>(() => !this.user);
}

The same was for the assignment and other cases. This pull request fixes this behavior.

Note: the delete operator was omitted intentionally because signal properties can be optional

@nx-cloud

nx-cloud Bot commented Mar 13, 2026

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit 9fb5db7

Command Status Duration Result
nx run-many -t test --configuration ci ✅ Succeeded 1m 4s View ↗
nx run-many -t build typecheck test check-rule-... ✅ Succeeded 5m 2s View ↗
nx-cloud record -- pnpm nx sync:check ✅ Succeeded 4s View ↗
nx-cloud record -- pnpm format-check ✅ Succeeded 7s View ↗
nx run-many -t test ✅ Succeeded 29s View ↗
nx run-many -t build ✅ Succeeded 12s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-17 07:50:34 UTC

@nx-cloud nx-cloud Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

At least one additional CI pipeline execution has run since the conclusion below was written and it may no longer be applicable.

Nx Cloud is proposing a fix for your failed CI:

We regenerated the auto-generated docs for the no-uncalled-signals rule to reflect the updated unary operator handling introduced in this PR. The eslint-plugin:check-rule-docs task performs a git diff check to ensure generated docs are in sync with the rule implementation, and this was failing because the docs hadn't been updated after the code change. Committing the regenerated documentation resolves the check.

Tip

We verified this fix by re-running eslint-plugin:check-rule-docs.

Suggested Fix changes
diff --git a/packages/eslint-plugin/docs/rules/no-uncalled-signals.md b/packages/eslint-plugin/docs/rules/no-uncalled-signals.md
index b0506218..7c3d414b 100644
--- a/packages/eslint-plugin/docs/rules/no-uncalled-signals.md
+++ b/packages/eslint-plugin/docs/rules/no-uncalled-signals.md
@@ -146,6 +146,65 @@ for (let i = 0; a; i++) { }
 
 #### ❌ Invalid Code
 
+​`​`​`ts
+function test(): boolean {
+  let a: Signal<boolean>;
+
+  return !a;
+          ~
+}
+​`​`​`
+
+<br>
+
+---
+
+<br>
+
+#### Default Config
+
+​`​`​`json
+{
+  "rules": {
+    "@angular-eslint/no-uncalled-signals": [
+      "error"
+    ]
+  }
+}
+​`​`​`
+
+<br>
+
+#### ❌ Invalid Code
+
+​`​`​`ts
+let a: Signal<boolean>;
+const flag = !a;
+              ~
+​`​`​`
+
+<br>
+
+---
+
+<br>
+
+#### Default Config
+
+​`​`​`json
+{
+  "rules": {
+    "@angular-eslint/no-uncalled-signals": [
+      "error"
+    ]
+  }
+}
+​`​`​`
+
+<br>
+
+#### ❌ Invalid Code
+
 ​`​`​`ts
 let a: Signal<boolean>;
 if (a) { }
@@ -1264,6 +1323,122 @@ let b = a;
 
 #### ✅ Valid Code
 
+​`​`​`ts
+let a: Signal<boolean>;
+let b = !a();
+​`​`​`
+
+<br>
+
+---
+
+<br>
+
+#### Default Config
+
+​`​`​`json
+{
+  "rules": {
+    "@angular-eslint/no-uncalled-signals": [
+      "error"
+    ]
+  }
+}
+​`​`​`
+
+<br>
+
+#### ✅ Valid Code
+
+​`​`​`ts
+let a: Signal<number>;
+let b = -a();
+​`​`​`
+
+<br>
+
+---
+
+<br>
+
+#### Default Config
+
+​`​`​`json
+{
+  "rules": {
+    "@angular-eslint/no-uncalled-signals": [
+      "error"
+    ]
+  }
+}
+​`​`​`
+
+<br>
+
+#### ✅ Valid Code
+
+​`​`​`ts
+class AppComponent {
+  prop = viewChild<AppComponent | undefined>();
+
+  test() {
+    delete this.prop;
+  }
+}
+​`​`​`
+
+<br>
+
+---
+
+<br>
+
+#### Default Config
+
+​`​`​`json
+{
+  "rules": {
+    "@angular-eslint/no-uncalled-signals": [
+      "error"
+    ]
+  }
+}
+​`​`​`
+
+<br>
+
+#### ✅ Valid Code
+
+​`​`​`ts
+function test(): boolean {
+  let a: Signal<boolean>;
+
+  return !a();
+}
+​`​`​`
+
+<br>
+
+---
+
+<br>
+
+#### Default Config
+
+​`​`​`json
+{
+  "rules": {
+    "@angular-eslint/no-uncalled-signals": [
+      "error"
+    ]
+  }
+}
+​`​`​`
+
+<br>
+
+#### ✅ Valid Code
+
 ​`​`​`ts
 function getSignal(): Signal<boolean> {}
 if (getSignal()()) { }

Because this branch comes from a fork, it is not possible for us to apply fixes directly, but you can apply the changes locally using the available options below.

Apply changes locally with:

npx nx-cloud apply-locally oLY1-Z3eI

Apply fix locally with your editor ↗   View interactive diff ↗



🎓 Learn more about Self-Healing CI on nx.dev

@JamesHenry JamesHenry left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See CI failure, our docs are generated from our unit tests so whenever they change the docs need to be regenerated.

There is a command you can run to fix it in the Nx Cloud comment

@BEGEMOT9I

Copy link
Copy Markdown
Contributor Author

@JamesHenry updated docs accordingly, thanks for pointing me out. Btw, why there is no CONTRIBUTING.md file?

@BEGEMOT9I BEGEMOT9I requested a review from JamesHenry March 14, 2026 18:20
@JamesHenry

Copy link
Copy Markdown
Member

@BEGEMOT9I they go stale and people ignore them anyway 😄

Thanks a lot for this contribution!

@JamesHenry JamesHenry merged commit 1000391 into angular-eslint:main Mar 17, 2026
5 checks passed
@codecov

codecov Bot commented Mar 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 0.00%. Comparing base (a959e4d) to head (9fb5db7).
⚠️ Report is 29 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #2926       +/-   ##
==========================================
- Coverage   90.88%       0   -90.89%     
==========================================
  Files         214       0      -214     
  Lines        5066       0     -5066     
  Branches     1609       0     -1609     
==========================================
- Hits         4604       0     -4604     
+ Misses        457       0      -457     
+ Partials        5       0        -5     
Flag Coverage Δ
unittest ?

Flags with carried forward coverage won't be shown. Click here to find out more.
see 214 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants