如何解决Firestore相关代码出现的TS2532: Object is possibly 'undefined'报错
报错原因
error TS2532: Object is possibly 'undefined' 报错触发的原因是Firestore SDK中DocumentSnapshot.data()方法的类型签名返回值为T | undefined(即可能返回undefined),即使你已经提前做了非空判断,TypeScript不会对两次独立调用的res.data()做关联类型推断,因此无法识别else分支中第二次调用的res.data()一定是非空值。
解决方案
下面是几种常用的解决方式,按推荐度排序:
- 方案1:提前存储
data()的返回值(最推荐)
把res.data()的结果提前赋值给一个变量,TypeScript会自动对这个变量做类型收窄,不会触发报错:useEffect(() => { firebase .firestore() .collection('likes') .doc(slug) .get() .then(res => { const docData = res.data() if (!docData) { console.log('No matching document'); } else { // 此时TS已经识别docData一定是非空值 setLikes(docData.likes); } }) .catch(err => console.log(err)); }, []); - 方案2:使用非空断言运算符
如果你100%确定else分支中res.data()一定存在,可以用!强制告诉TypeScript该值不为空:setLikes(res.data()!.likes); - 方案3:使用可选链+空值合并兜底
如果你需要兼容数据不存在的场景,同时避免运行时报错,可以用可选链?.读取属性,再加空值合并运算符??给默认值:// 兜底默认值可根据你的业务逻辑调整,比如0、空字符串等 setLikes(res.data()?.likes ?? 0); - 方案4:定义文档类型泛型(提升类型安全)
你可以提前定义该Firestore文档的TS类型,调用data()时传入泛型,进一步提升类型安全性:// 定义文档对应的类型 interface LikesDoc { likes: number } // 调用时传入泛型 const docData = res.data<LikesDoc>()
内容的提问来源于stack exchange,提问作者Alexander VT
相关产品推荐
相关产品推荐

