htmlangulartypescriptangular-signals

Assume that a signal isn't empty when used inside an @if?


Let's assume you have the following code:

$mySignal = signal<number | undefined>(1)
@if ($mySignal()) {
  <foo [item]="$mySignal()"></foo>
}

I got:

Type 'number | undefined' is not assignable to type 'number'. Type 'undefined' is not assignable to type 'number'.

What is the best way to solve this error?


Solution

  • The issue could be caused due to accessing directly via the signal function in multiple places. The types are evaluated across all signal function calls, hence the types are evaluating separately, hence causing typescript issues. Related Github issue below.

    signals: TypeScript and nullability #49161

    Instead we can leverage @let or @if(<<cond>>; as propName) to narrow the type once and access them across multiple places.


    Using @let:

    You can also perform type narrowing using @let syntax, if hiding the element is not needed, we can get rid of the @if.

    @let mySignal = $mySignal();
    <foo [item]="mySignal"></foo>
    

    Using @if(<<cond>>; as propName):

    You can use as syntax, do the null check and also use the property inside the if condition.

    @if($mySignal(); as mySignal){
      <foo [item]="mySignal"></foo>
    }
    

    Using !:

    You can infer that the variable does contain a value with !

    @if ($mySignal()) {
      <foo [item]="$mySignal()!"></foo>
    }
    

    Stackblitz Demo