You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firestore 9 onSnapshot中展开doc.data()报TS2698错误是什么原因?

报错根因

Firestore 9 中 DocumentSnapshot 的 data() 方法返回类型为泛型 T | undefined,而非绝对的对象类型:

  • 当目标文档不存在时,data() 会返回 undefined,对 undefined 执行展开操作会触发运行时报错,TypeScript 的类型校验提前拦截了该风险。
  • 代码未对 doc 做存在性校验,也没有给集合绑定明确的泛型结构,TypeScript 无法确认 doc.data() 一定为对象类型,因此抛出 Spread types may only be created from object types. ts(2698) 错误。
可行解决方案

方案1:增加文档存在性判断(最安全,无运行时风险)

调用 data() 前先通过 doc.exists() 校验文档是否存在,校验通过后 TypeScript 会自动将 data() 的返回类型收窄为对象:

const unsubscribe = onSnapshot(
    collectionOrdered,
    (snapshot) => {
      snapshot.docs.forEach((doc) => {
        // 新增存在性判断
        if (doc.exists()) {
          documents.push({ ...doc.data(), id: doc.id });
        }
      });
      error.value = null;
      console.log(documents);
    },
    (err) => {
      console.log(err.message);
      documents.splice(0);
      error.value = err.message;
    }
  );

方案2:绑定集合泛型+非空断言(适合确认返回文档必定存在的场景)

首先定义对应文档的数据结构,给集合指定泛型后,通过 ! 非空断言明确告知 TypeScript data() 不会返回 undefined:

// 第一步:定义文档结构泛型
interface DocType {
  // 按需填写你的文档字段,示例如下
  title: string
  createTime: number
  author: string
}
// 第二步:定义集合时指定泛型
const collectionOrdered = collection<DocType>(db, '你的集合名称')

// 第三步:展开时添加非空断言
documents.push({ ...doc.data()!, id: doc.id })

方案3:强制类型断言(适合快速调试场景)

如果不需要严格校验,可以直接将 doc.data() 强制断言为对象类型:

documents.push({ ...doc.data() as Record<string, any>, id: doc.id })

内容的提问来源于stack exchange,提问作者TinyTiger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 23:36:04