0

I have a function with an argument. This argument needs to be one of two kind of interfaces. So i write it like this:

 add(item: IntDroga | IntSolucion){
  if(item && item.identificacion){
   if(item.estado.habilitada.value == false || item.estado.estado == estadoAprobacion.Aprobado){ 
    // some code
   }
  }
 }

But i recieve the following error.

    Property 'habilitada' does not exist on type '{ estado: string; habilitada: { value: boolean; viewValue: string; }; excluida: boolean; } | { estado: estadoAprobacion; fecha: Date; usuario: string; }'.
  Property 'habilitada' does not exist on type '{ estado: estadoAprobacion; fecha: Date; usuario: string; }'.ts(2339)

Here are the interfaces:

IntDroga:

export interface IntDroga {
    _id: string;
    identificacion: {
            nombre: string,
            codigo: string,
            marca: string,
            grupoSustancias: string,
            nProducto: string,
            lote: string,
            CAS: string,
            codigoAlternativo: string,
            estandarInterno: boolean
    };
    informacion: {
            pureza: number,
            humedad: number,
            fecha: {
                    fabricacion: Date,
                    recepcion: Date,
                    vencimientoCertificado: Date,
                    vencimientoAsignada: Date,
            },
            presentacion: string,
            solucion?: { concentracion: number, unidad: string},
            cantidad: {
                    recibida: {valor: number, unidad: string},
                    remanente: {valor: number, unidad: string},
                    unidad: string,
            },
            concentracion?: {valor: number, unidad: string},
            DLDC: {
                    libre: {value: boolean, viewValue: string},
                    masaDL: number,
                    masaDC: number,
                    fDLDC: number,
            };
            sectores: string [];
            rubros: string [];
            ubicacion: string;
            observaciones: string;
    };
    estado: {
            estado: string,
            habilitada: {value: boolean, viewValue: string},
            excluida: boolean
    };
}

IntSolucion:

export interface IntSolucion {
_id: string,
identificacion: {
    nombre: string,
    codigo: string,
},
informacion:{
    tipo: string,
    componentes: Componente [] ,
    fecha:{
        preparacion: Date,
        vencimiento: Date,
        descarte: Date
    },
    material:{
        matraz: {
            codigo: string,
            volumen: {value: number, unidad: string}
        }
    },
    temperaturaPreparacion: string,
    almacenamiento: string
    analista: string,
    solvente: {tipo: string, identificacion: string}
},
estado?: {estado:estadoAprobacion, fecha: Date, usuario: string};
};

I can´t undestand what´s the problems. It is supposed that the function´s argument can have two different structures. I don´t know why Tslink marks it.

Thank you in advance for your help.

R. Richards
  • 24,603
  • 10
  • 64
  • 64
Javier salvañá
  • 191
  • 2
  • 16
  • You should take a look at typescrit typeguard: https://www.typescriptlang.org/docs/handbook/advanced-types.html – ukn Jul 02 '20 at 17:47
  • That's because `IntSolucion` doesn't have the property `habilitada` in the field `estado`. – Nicholas K Jul 02 '20 at 17:48

1 Answers1

1

It seems the IntSolucion doesn't have the property "habilitada" on "estado" object. Maybe, you can change to this:

add(item: IntDroga | IntSolucion){
  if(item && item.identificacion){
    if(((item instaceof IntDroga) && item.estado.habilitada.value == false) || item.estado.estado == estadoAprobacion.Aprobado) { 
     // some code
    }
  }
}

Another approach is do some type condition:

if (item instanceof IntDroga) {
  // do the stuff assuming an IntDrog instance
} else {
  // do the stuff assuming an IntSolucion instance
}
Danilo Torchio
  • 381
  • 2
  • 8
  • Hello thank you for your help, so in typescript i can write `(item: IntDroga | IntSolucion)` saying that item can have the structure of one of those interfaces but anyway in the code below i have to continue differentiating the code for each case? – Javier salvañá Jul 02 '20 at 17:58
  • Yes, you need to differentiate. Thinking about the javascript translation, if during execution the item is an instance of IntSolucion, the execution will throw an exception "cannot read property value of undefined" (because "habilitada" is undefined). If you use the first approach or use `item.estado.habilitada?.value` (look the ? character) you may not receive the error but I think tslink will continue to mark it. – Danilo Torchio Jul 02 '20 at 18:17
  • Understood, the problem i have now is that whith this approach `if (item instanceof IntDroga)` i get the error `'IntDroga' only refers to a type, but is being used as a value here.ts(2693)` – Javier salvañá Jul 02 '20 at 18:29
  • I see, it's because IntDroga is an Interface, not a Class, right? You cannot do that with interfaces because interfaces are removed on compilation. Maybe with [type guards](https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types). Look at this [answer](https://stackoverflow.com/a/46703380/5264995). – Danilo Torchio Jul 02 '20 at 18:40