Search code examples
angulartypescriptangular-signals

Angular Switch with multiple types


I used to make this trick in my latest projects which was

  results = signal<
    | { state: 'error'; error: string }
    | { state: 'normal' }
    | { state: 'success'; message: string }
    | { state: 'loading' }
  >({ state: 'normal' });

giving results multiple types. and in HTML

@switch (results().state) {
  @case ("error") {
    <div role="alert" class="alert alert-error">
      <svg
        xmlns="http://www.w3.org/2000/svg"
        class="h-6 w-6 shrink-0 stroke-current"
        fill="none"
        viewBox="0 0 24 24"
      >
        <path
          stroke-linecap="round"
          stroke-linejoin="round"
          stroke-width="2"
          d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
        />
      </svg>
      <span>{{ results().error }}</span>
    </div>
  }
}

which worked fine before, However in my latest project it says

Property 'error' does not exist on type '{ state: "error"; error: string; } | { state: "normal"; } | { state: "success"; message: string; } | { state: "loading"; }'. Property 'error' does not exist on type '{ state: "normal"; }'

Is there any settings I should tweek to make it work again?


Solution

  • Use @let and do the following instead:

    @let r = results();
    @switch (r.state) {
      @case ("error") {
        <div role="alert" class="alert alert-error">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            class="h-6 w-6 shrink-0 stroke-current"
            fill="none"
            viewBox="0 0 24 24"
          >
            <path
              stroke-linecap="round"
              stroke-linejoin="round"
              stroke-width="2"
              d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
            />
          </svg>
          <span>{{ r.error }}</span>
        </div>
      }
    }
    

    The idea is to call results() once and determine its type. Calling again raises the possibility that it is not of type error