Estoy tratando de reconstruir un ejemplo de aplicación web que usa Firebase Cloud Functions y Firestore. Al implementar una función me sale el siguiente error:
src/index.ts:45:18 - error TS2532: Object is possibly 'undefined'. 45 const data = change.after.data();Esta es la función:
export const archiveChat = functions.firestore .document("chats/{chatId}") .onUpdate(change => { const data = change.after.data(); const maxLen = 100; const msgLen = data.messages.length; const charLen = JSON.stringify(data).length; const batch = db.batch(); if (charLen >= 10000 || msgLen >= maxLen) { // Always delete at least 1 message const deleteCount = msgLen - maxLen <= 0 ? 1 : msgLen - maxLen data.messages.splice(0, deleteCount); const ref = db.collection("chats").doc(change.after.id); batch.set(ref, data, { merge: true }); return batch.commit(); } else { return null; } });Solo estoy tratando de implementar la función para probarla. Y ya busqué en la web problemas similares, pero no pude encontrar ninguna otra publicación que coincida con mi problema.
Para otros que enfrentan un problema similar al mío, donde sabe que una propiedad de objeto en particular no puede ser nula, puede usar el operador de afirmación no nula (!) después del elemento en cuestión. Este fue mi código:
const naciStatus = dataToSend.naci?.statusNACI; if (typeof naciStatus != "undefined") { switch (naciStatus) { case "AP": dataToSend.naci.certificateStatus = "FALSE"; break; case "AS": case "WR": dataToSend.naci.certificateStatus = "TRUE"; break; default: dataToSend.naci.certificateStatus = ""; } } Y debido a que dataToSend.naci no se puede definir en la declaración de cambio, el código se puede actualizar para incluir signos de exclamación de la siguiente manera:
const naciStatus = dataToSend.naci?.statusNACI; if (typeof naciStatus != "undefined") { switch (naciStatus) { case "AP": dataToSend.naci!.certificateStatus = "FALSE"; break; case "AS": case "WR": dataToSend.naci!.certificateStatus = "TRUE"; break; default: dataToSend.naci!.certificateStatus = ""; } }Con el lanzamiento de TypeScript 3.7, el encadenamiento opcional (el operador ? ) ahora está oficialmente disponible.
Como tal, puede simplificar su expresión a lo siguiente:
const data = change?.after?.data();Puede obtener más información al respecto en las notas de publicación de esa versión, que cubren otras características interesantes publicadas en esa versión.
Ejecute lo siguiente para instalar la última versión estable de TypeScript.
npm install typescript Dicho esto, el encadenamiento opcional se puede usar junto con la fusión nula para proporcionar un valor de respaldo cuando se trata de valores null o undefined .
const data = change?.after?.data() ?? someOtherData();Puntos adicionales:
Si está utilizando el encadenamiento opcional en las sentencias if condicionales, aún deberá asegurarse de que está realizando una verificación de igualdad de valor/tipo adecuada.
Lo siguiente fallará en TypeScript estricto, ya que posiblemente esté comparando un valor indefinido con un número.
if (_?.childs?.length > 0)En cambio, esto es lo que deberías estar haciendo:
if (_?.childs && _.childs.length > 0)Si está utilizando Typescript 3.7 o posterior, ahora también puede hacer:
const data = change?.after?.data(); if(!data) { console.error('No data here!'); return null } const maxLen = 100; const msgLen = data.messages.length; const charLen = JSON.stringify(data).length; const batch = db.batch(); if (charLen >= 10000 || msgLen >= maxLen) { // Always delete at least 1 message const deleteCount = msgLen - maxLen <= 0 ? 1 : msgLen - maxLen data.messages.splice(0, deleteCount); const ref = db.collection("chats").doc(change.after.id); batch.set(ref, data, { merge: true }); return batch.commit(); } else { return null; } Typescript dice que el change o data posiblemente no estén undefined (dependiendo de lo que devuelva onUpdate ).
Por lo tanto, debe envolverlo en un cheque nulo/indefinido:
if(change && change.after && change.after.data){ const data = change.after.data(); const maxLen = 100; const msgLen = data.messages.length; const charLen = JSON.stringify(data).length; const batch = db.batch(); if (charLen >= 10000 || msgLen >= maxLen) { // Always delete at least 1 message const deleteCount = msgLen - maxLen <= 0 ? 1 : msgLen - maxLen data.messages.splice(0, deleteCount); const ref = db.collection("chats").doc(change.after.id); batch.set(ref, data, { merge: true }); return batch.commit(); } else { return null; } } Si está 100% seguro de que su object siempre está definido, puede poner esto:
const data = change.after!.data();