En mi componente Angular tengo una Input que se proporcionará 1 de 2 tipos.
@Input() profile: UserProfileDetails | BusinessProfileDetails;La plantilla de perfil es simple y me gustaría usar solo la plantilla única para no duplicar el código. Pero debido a que los tipos difieren en las propiedades, recibo un error de plantilla.
export interface UserProfileDetails { createdOn: Date; id: string; name: string; } export interface BusinessProfileDetails { businessId: string; businessLocation: string; createdOn: Date; id: string; name: string; }y el código en mi plantilla:
<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> Creo que entiendo por qué recibo el error, pero no estoy seguro de cómo resolver el problema mientras sigo usando el perfil or la condición @Input() profile: UserProfileDetails | BusinessProfileDetails;
Solo puede hacer referencia a propiedades que son comunes a ambas interfaces con | . Instintivamente | se llama un tipo de union en TypeScript.
Pruebe un tipo de intersección con & en su lugar
Puede configurar una solución utilizando una función que verifique el atributo en el profile usando in operador. No es la mejor solución, pero podrá mantener la unión de interfaces como desee:
Componente
getValue( attribut: string, obj: UserProfileDetails | BusinessProfileDetails ): any { if (attribut in obj) { return obj[attribut]; } }Plantilla
<div> <h1>{{ profile.name }}</h1> <div>{{ profile.createdOn }}</div> <div>{{ profile.id }}</div> <div>{{ getValue('businessId', profile) }}</div> <!-- can be improved using a check method combined with ngIf --> <div>{{ getValue('businessLocation', profile) }}</div> </div>El problema al que se enfrenta es que la verificación del tipo de plantilla de angular parece estar habilitada.
Con la configuración relacionada habilitada, se validan los tipos de objetos utilizados en la vista. Si por casualidad el objeto no tuviera una de las propiedades, estas validaciones causarían el error al que te enfrentas.
Específicamente en su caso, debido a que la interfaz UserProfileDetails no tiene algunas de las propiedades utilizadas en la vista, angular está considerando el uso de businessId o businessLocation como un error.
hay algunas opciones para solucionarlo:
profile (tampoco preferiría este) <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 } }También puedes probar con:
<div *ngIf="profile.hasOwnProperty('businessId')">{{profile.businessId}}</div> <div *ngIf="profile.hasOwnProperty('businessLocation')">{{profile.businessLocation}}</div>vaya al archivo tsconfig y cambie el modo estricto (línea 8 si no recuerdo mal) a false