#Using union type in template with signal ?

3 messages · Page 1 of 1 (latest)

orchid lantern
#

Hello guys, is possible to use union type with signal in template ?

I have 2 interfaces and a type

`export interface ProductResponse<T> {
products: T;
total: number;
skip: number;
limit: number;
}

export interface UserResponse<T> {
users: T;
total: number;
skip: number;
limit: number;
}

export type ApiResponse<T> = ProductResponse<T> | UserResponse<T>;`

an a interface for my signal

export interface VmSignal<T> { data: T | null; loading: boolean; error: string | null; }

then, I use them like that

productsSignal: Signal<VmSignal<ApiResponse<Product[]>> | undefined> = toSignal( this._productService.getAll().pipe( map((result) => ({ data: result, error: null, loading: false, })), startWith({ data: null, loading: true, error: null }), catchError((error) => of({ data: null, error: 'error', loading: false }) ) ) );

But my template does not recognize the product property.

{ @for (product of productsSignal()?.data?.products; track $index) { <p-card> <h2>{{ product }}</h2> <div class="flex gap-2 flex-row align-items-start justify-content-center"> <img src="../../assets/images/img-product.png" alt="" /> <div class="info"> <p class="font-bold">{{ product.price }}</p> <p class="font-bold">{{ product.description }}</p> </div> </div> </p-card> }

data.products not exist.
Look like is not really possible

grizzled plume
#

The error message is not "data.products not exist.". it is

Property 'products' does not exist on type 'ApiResponse<Product[]>'.
  Property 'products' does not exist on type 'UserResponse<Product[]>'

And indeed, since your VmSignal can contain any kind of ApiResponse<Product[]>, it could be a UserResponse<Product[]>, which doesn't have a products property.
Use a discriminated union type, or makes things simpler by typing your signal with the unique type you're expecting it to hold, i.e. Signal<VmSignal<ProductResponse<Product[]>> | undefined>.
So this has nothing to do with templates or signals. Just has to do with TypeScript making sure you're not doing incorrect things.

orchid lantern
#

Ok so there's really no way to tell that what I'm receiving is of type "Product" in the template.

I'll make things simpler.
Just curious, thanks