React组件间传递异步函数时出现Type Error问题求助
父组件代码
const [downloadUrls, setDownloadUrls] = useState<string[]>([]); const [preview, setPreview] = useState<string[]>([]); const [loading, setLoading] = useState(false); // 补充缺失的loading状态 const uploadingToFB = async () => { setLoading(true); // 将promises声明移到函数内部,避免重复累积上传任务 const promises: Promise<string>[] = []; try { for (let i = 0; i < preview.length; i++) { const productRef = ref(storage, `images/${uuidv4()}.jpg`); // 简化Promise写法,去掉不必要的嵌套包装 const uploadPromise = uploadString(productRef, preview[i], "data_url") .then(snapshot => getDownloadURL(snapshot.ref)); promises.push(uploadPromise); } const values = await Promise.all(promises); setDownloadUrls(values); setLoading(false); } catch (error) { console.log(error); setLoading(false); // 错误时也要重置loading状态 } } <ButtonSaveProduct uploadingToFB={uploadingToFB}></ButtonSaveProduct>
子组件(原路径:app/ButtonSaveProduct/page.tsx)代码
import React from "react"; type PAGEPROPS = { uploadingToFB: () => Promise<void>; }; export default function ButtonSaveProduct({ uploadingToFB }: PAGEPROPS) { return ( <button className="p-4 bg-blue-950 text-white rounded-md hover:bg-blue-200" onClick={uploadingToFB}> save </button> ); }
本地运行错误
Type 'OmitWithTag<PAGEPROPS, keyof PageProps, "default">' does not satisfy the constraint '{ [x: string]: never; }'.
Property 'uploadingToFB' is incompatible with index signature.
Type '() => void' is not assignable to type 'never'.
Vercel部署错误
Type error: Page "app/ButtonSaveProduct/page.tsx" has an invalid "default" export:
Type "{ uploadingToFB: () => void; }" is not valid
解决方案
修复核心路由组件类型错误
Next.js App Router规定,app目录下的page.tsx是路由页面组件,只能接收框架预定义的props(如searchParams、params),不能自定义props。你把ButtonSaveProduct放在了app/ButtonSaveProduct/page.tsx,导致它被识别为路由页面,传递自定义props时触发类型冲突。解决:将
ButtonSaveProduct组件移到components目录下(比如components/ButtonSaveProduct.tsx),作为普通业务组件使用,即可正常接收自定义的uploadingToFBprops。优化异步上传逻辑
- 将
promises数组的声明移到uploadingToFB函数内部,避免组件多次渲染时累积历史上传任务。 - 简化Promise嵌套写法,去掉不必要的
new Promise包装,直接用链式调用处理上传和下载地址获取流程。 - 在catch分支中重置
loading状态,避免页面因错误一直处于加载状态。
- 将
内容的提问来源于stack exchange,提问作者Captai-N

