typescript 如何解决错误“TS2532:对象可能是“未定义”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/54884488/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 08:02:04  来源:igfitidea点击:

How can I solve the error 'TS2532: Object is possibly 'undefined'?

typescriptfirebasegoogle-cloud-firestoregoogle-cloud-functions

提问by Constantin Beer

I'm trying to rebuild a web app example that uses Firebase Cloud Functions and Firestore. When deploying a function I get the following error:

我正在尝试重建一个使用 Firebase Cloud Functions 和 Firestore 的网络应用程序示例。部署函数时出现以下错误:

src/index.ts:45:18 - error TS2532: Object is possibly 'undefined'.
45     const data = change.after.data();

This is the function:

这是函数:

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;
    }
  });

I'm just trying to deploy the function to test it. And already searched the web for similar problems, but couldn't find any other posts that match my problem.

我只是想部署该功能来测试它。并且已经在网上搜索了类似的问题,但找不到与我的问题相匹配的任何其他帖子。

采纳答案by wentjun

As of October 2019, optional chaining (the ?operator) is now available on TypeScript 3.7 (Beta). You may install that version by running the following command:

自 2019 年 10 月起,?TypeScript 3.7(测试版)现在可以使用可选链(运算符)。您可以通过运行以下命令来安装该版本:

npm install typescript@beta

As such, you can simplify your expression to the following:

因此,您可以将表达式简化为以下内容:

const data = change?.after?.data();

You may read more about it from the release notes, which cover other interesting features released on that version.

您可以从发行说明 中阅读更多相关信息,其中涵盖了该版本发布的其他有趣功能。

Update (as of November 2019)

更新(截至 2019 年 11 月)

TypeScript's optional chaining is now officially available. Installing the latest version of typescript should allow you to access the cool new features.

TypeScript 的可选链接现已正式可用。安装最新版本的 typescript 应该允许您访问很酷的新功能。

npm install typescript

That being said, Optional Chainingcan be used alongside Nullish Coalescingto provide a fallback value when dealing with nullor undefinedvalues

话虽如此,Optional Chaining可以与Nullish Coalescing一起使用,以在处理nullorundefined值时提供后备值

const data = change?.after?.data() ?? someOtherData();

回答by distante

Edit / Update:

编辑/更新:

If you are using Typescript 3.7 you can now also do:

如果您使用的是 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;
    }

Original Response

原始回复

Typescript is saying that changeor datais possibly undefined(depending on what onUpdatereturns).

打字稿正在说changedata可能undefined(取决于onUpdate返回的内容)。

So you should wrap it in a null/undefined check:

所以你应该把它包装在一个空/未定义的检查中:

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;
    }
}

If you are 100% sure that your objectis always defined then you can put this:

如果您 100% 确定您object的始终是定义的,那么您可以这样写:

const data = change.after!.data();