我正在尝试重建一个使用 Firebase Cloud Functions 和 Firestore 的 Web 应用程序示例。部署函数时出现以下错误:
src/index.ts:45:18 - error TS2532: Object is possibly 'undefined'.
45 const data = change.after.data();
这是功能:
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;
}
});
我只是试图部署该功能来测试它。并且已经在网上搜索了类似的问题,但找不到与我的问题匹配的任何其他帖子。
随着 TypeScript 3.7 的发布,可选链(?
运算符)现在正式可用。
因此,您可以将表达式简化为以下内容:
const data = change?.after?.data();
您可以从该版本的 release notes 中了解更多信息,其中涵盖了该版本发布的其他有趣功能。
运行以下命令来安装最新的稳定版 TypeScript。
npm install typescript
话虽如此,在处理 null
或 undefined
值时,Optional Chaining 可以与 Nullish Coalescing 一起使用以提供备用值
const data = change?.after?.data() ?? someOtherData();
附加点:
如果您在条件 if
语句中使用可选链接,您仍然需要确保您正在执行正确的值/类型相等性检查。
以下将在严格的 TypeScript 中失败,因为您可能正在将未定义的值与数字进行比较。
if (_?.childs?.length > 0)
相反,这是你应该做的:
if (_?.childs && _.childs.length > 0)
编辑/更新:
如果您使用的是 Typescript 3.7 或更高版本,您现在还可以执行以下操作:
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;
}
原始回复
打字稿说 change
或 data
可能是 undefined
(取决于 onUpdate
返回的内容)。
所以你应该把它包装在一个空/未定义的检查中:
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;
}
}
如果您 100% 确定您的 object
始终被定义,那么您可以这样写:
const data = change.after!.data();
error TS7030: Not all code paths return a value. 44 .onUpdate((change, context) =>
if
语句返回 false 时,您现在需要返回一些内容。
data
对象添加一个 if 查询,并且只是在 else 分支中添加了 return null;
。有没有更清洁的方法来实现它? #HugeDougFan
const data = change!.after!.data()
我得到一个错误,但使用 const data = change.after!.data()
它可以工作。十分感谢。 :)
对于面临与我类似的问题的其他人,您知道特定对象属性不能为空,您可以在相关项目之后使用非空断言运算符 (!)。这是我的代码:
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 = "";
}
}
并且由于不能在 switch 语句中取消定义 dataToSend.naci
,因此可以更新代码以包含感叹号,如下所示:
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 = "";
}
}
images
可选字段吗?这就是为什么它可能是undefined
?在这种情况下,你想试试这个吗?if (listingData?.images) { image = listingData?.images?.[0].imageUrl; }
"strictNullChecks": false,
添加到 tsconfig.json 文件。