Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Property does not exist on type when using Or for multiple types

In my Angular component I have an Input that will be provided 1 of 2 types.

@Input() profile: UserProfileDetails | BusinessProfileDetails;

The profile template is simple and I'd like to use only the single template so I am not duplicating code. But because the types differ in properties I am receiving a template error.

export interface UserProfileDetails {
  createdOn: Date;
  id: string;
  name: string;
}
export interface BusinessProfileDetails {
  businessId: string;
  businessLocation: string;
  createdOn: Date;
  id: string;
  name: string;
}

and the code in my template:

<div>
  <h1>{{profile.name}}</h1>
  <div>{{profile.createdOn}}</div>
  <div>{{profile.id}}</div>
  <div *ngIf="profile?.businessId">{{profile.businessId}}</div>
  <div *ngIf="profile?.businessLocation">{{profile.businessLocation}}</div>
</div>

I believe I understand why I am receiving the error, but I'm unsure how to resolve the issue while still using the or condition @Input() profile: UserProfileDetails | BusinessProfileDetails;

like image 897
andthegrindbegins Avatar asked May 30 '26 10:05

andthegrindbegins


2 Answers

The issue you are facing is that angular's Template type checking seems enabled.

With the related settings enabled, the types of the objects used within the view are validated. If by any chance the object would not have one of the properties, these validations would cause the error you are facing.

Specifically in your case because the interface UserProfileDetails does not have some of the properties used in the view, angular is considering the use of businessId or businessLocation an error.

there are some options to fix it:

  • disable Template type checking (I would not recommend that)
  • use a generic type for the profile variable (I would also not prefer this one)
  • use a pipe to cast the type of the object within the view. (my preference)
<div *ngIf="(profile | castProfileType)?.businessId">{{profile.businessId}}</div>
<div *ngIf="(profile | castProfileType)?.businessLocation">{{profile.businessLocation}}</div>
@Pipe({
    name: 'castProfileType',
})
export class CastProfileTypePipe implements PipeTransform {
  transform(value: profileObject) {
    return Object.keys(value).includes('businessId') ? <BusinessProfileDetails>value : <UserProfileDetails>value
  }
}
like image 174
The Fabio Avatar answered Jun 01 '26 23:06

The Fabio


You can also try with:

<div *ngIf="profile.hasOwnProperty('businessId')">{{profile.businessId}}</div>
<div *ngIf="profile.hasOwnProperty('businessLocation')">{{profile.businessLocation}}</div>
like image 39
Misha Mashina Avatar answered Jun 02 '26 01:06

Misha Mashina



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!