Para empezar: soy un novato total de TypeScript, así que tengan paciencia conmigo.
Hice un pequeño caso de uso (en la parte inferior de esta publicación) en el que tengo una matriz que puede contener tanto "Clase uno" como "Clase dos". Quiero recorrer esa matriz con forEach y actuar cuando el drawer de propiedades esté presente.
El problema que me da Typescript en mi bucle forEach (donde intento registrar el drawer ) es:
Property 'drawer' does not exist on type 'One | Two'. Property 'drawer' does not exist on type 'Two'. Si bien está claramente presente en One .
Cuando configuro mi arrayWithBothOneAndTwo para let arrayWithBothOneAndTwo = [] as One[] , no me dará el problema de que el cajón no existe en mi ciclo forEach, pero dado que contiene Two, no creo que sea una solución adecuada y lanzaré otra errores
Cambiando mi bucle forEach a
arrayWithBothOneAndTwo.forEach((item: One) => { console.log(item.drawer) })me da el error:
Argument of type '(item: One) => void' is not assignable to parameter of type '(value: One | Two, index: number, array: (One | Two)[]) => void'. Types of parameters 'item' and 'value' are incompatible. Type 'One | Two' is not assignable to type 'One'. Property 'drawer' is missing in type 'Two' but required in type 'One'.Así que en resumen:
¿Cómo puedo usar item.drawer en mi forEach sin arrojar errores en mi código?
class One { drawer: string[] = [] constructor () { this.drawer.push('A') this.drawer.push('B') this.drawer.push('C') } } class Two { notADrawer: string[] = [] constructor () { this.notADrawer.push('D') this.notADrawer.push('E') this.notADrawer.push('F') } } // make an array with some one classes const someOnes = [new One(), new One()] // make an array with some two classes const someTwos = [new Two(), new Two(), new Two(), new Two()] // init an array which can contain both One or Two let arrayWithBothOneAndTwo = [] as Array<One | Two> // populate array with some One classes and some Two classes arrayWithBothOneAndTwo = [...someOnes, ...someTwos] // Loop through it and show the drawer array (if present) arrayWithBothOneAndTwo.forEach((item) => { console.log(item.drawer) })Para que TypeScript reduzca correctamente el tipo, debe agregar una verificación para ver si la propiedad está presente:
arrayWithBothOneAndTwo.forEach((item) => { if('drawer' in item) { console.log(item.drawer); // type of item now narrowed to One } });Si lo desea, puede hacerlo más explícito con un predicado de tipo en una protección de tipo definida por el usuario:
arrayWithBothOneAndTwo.forEach((item) => { if(isOne(item)) { console.log(item.drawer); } }); function isOne(item: One | Two): item is One { return 'drawer' in item; }