web-dev-qa-db-ja.com

エラー「TS2532:オブジェクトはおそらく「未定義」です」を解決するにはどうすればよいですか?

Firebase Cloud FunctionsとFirestoreを使用するウェブアプリの例を再構築しようとしています。関数をデプロイすると、次のエラーが発生します。

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

私はそれをテストするために関数をデプロイしようとしています。すでに同様の問題をウェブで検索しましたが、私の問題に一致する他の投稿は見つかりませんでした。

29
Constantin Beer

2019年10月現在、オプションのチェーン(?演算子)がTypeScript 3.7(ベータ)で利用可能になりました。次のコマンドを実行して、そのバージョンをインストールできます。

npm install TypeScript@beta

そのため、式を次のように簡略化できます。

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

詳細は リリースノート を参照してください。このバージョンでリリースされた他の興味深い機能について説明しています。

更新(2019年11月現在)

TypeScriptのオプションのチェーンが正式に利用可能になりました。 TypeScriptの最新バージョンをインストールすると、クールな新機能にアクセスできるようになります。

npm install TypeScript

つまり、 オプションのチェーンNullish Coalescing と併用して、nullまたはundefinedの値を処理するときにフォールバック値を提供できます。

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

TypeScriptは、changeまたはdataundefinedである可能性があると言っています(onUpdateが返す内容によって異なります)。

したがって、それをnull /未定義のチェックでラップする必要があります。

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

あなたのobjectが常に定義されていることを100%確信しているなら、これを置くことができます:

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