使用react-hook-form上传文件至Firebase时遇TS7053类型错误求助
解决TS7053错误:无法用索引0访问
string | File类型 问题原因
你的RecipeUpload类型定义中,image被声明为File | string,但表单提交后实际拿到的是FileList类型(<input type="file">返回的是FileList对象)。TypeScript无法确定e.image到底是string还是File,而这两种类型都不支持用数字索引[0]访问,因此抛出TS7053错误。
解决方案
方案1:拆分类型(推荐,类型更严谨)
区分表单提交数据类型和最终上传后的数据类型——表单提交时image是FileList,上传完成后才变为string(Firebase存储URL):
// 表单提交时的临时数据类型 type RecipeFormData = { title: string; descr: string; by: string; image: FileList; // 匹配input file返回的FileList类型 }; // 最终上传到数据库的类型 type RecipeUpload = { title: string; descr: string; by: string; image: string; // 存储Firebase文件URL };
修改上传代码,基于RecipeFormData处理:
// 假设e是RecipeFormData类型 const file = e.image[0]; uploadBytes(img, file).then(data => { getDownloadURL(data.ref).then(val => { // 转换为RecipeUpload类型 const recipeData: RecipeUpload = { ...e, image: val }; console.log(recipeData, val); }).catch(err => console.log(err)); }).catch(err => console.log(err));
方案2:类型守卫/断言(快速修复)
如果不想修改类型定义,可通过类型守卫或断言告诉TypeScript当前e.image是FileList:
方式A:类型守卫(安全)
// 定义类型守卫函数 function isFileList(value: unknown): value is FileList { return value instanceof FileList; } // 使用类型守卫判断 if (isFileList(e.image)) { uploadBytes(img, e.image[0]).then(data => { getDownloadURL(data.ref).then(val => { e.image = val; console.log(e, val); }).catch(err => console.log(err)); }).catch(err => console.log(err)); }
方式B:类型断言(简便,需确保类型正确)
// 直接断言e.image为FileList uploadBytes(img, (e.image as FileList)[0]).then(data => { getDownloadURL(data.ref).then(val => { e.image = val; console.log(e, val); }).catch(err => console.log(err)); }).catch(err => console.log(err));
内容的提问来源于stack exchange,提问作者Roderen
相关产品推荐
相关产品推荐

