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
相关产品推荐
相关产品推荐

