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

如何在React+TS中处理Firestore返回的Promise<DocumentData[] | undefined>?

解决async函数返回Promise类型错误与TypeScript类型匹配问题

问题1:直接对Promise调用map导致的类型错误

getMeds()是异步函数,返回的是Promise<DocumentData[] | undefined>而非直接的数组,所以不能直接调用map。必须通过await等待Promise解析完成,拿到实际数组后才能进行map操作——你在fetchDocuments里已经正确使用了await,之前的错误应该是没加await就直接写getMeds().map(...)导致的。

问题2:TypeScript类型不匹配问题

步骤1:导入Firebase的DocumentData类型

先确保导入Firestore的类型定义:

import { DocumentData } from "firebase/firestore";

步骤2:明确getMeds的返回类型并处理边界情况

给getMeds()指定返回类型,同时处理无用户时的返回值(原代码无用户时会隐式返回undefined,我们让它返回空数组,避免后续额外处理):

export const getMeds = async (): Promise<DocumentData[]> => {
    try {
        const user = auth.currentUser;
        if (user) {
            const snapshot = await getDocs(collection(db, "Users", user.uid, "Medications"));
            return snapshot.docs.map(doc => doc.data());
        }
        // 无用户时返回空数组,消除undefined类型
        return [];
    } catch (err: any) {
        throw new Error(err.message);
    }
}

步骤3:正确定义useState的类型

现在可以给useState指定DocumentData[]类型,初始值设为空数组:

import { useState, useEffect } from "react";
import { DocumentData } from "firebase/firestore";
import { getMeds } from "./your-file-path"; // 替换为你的实际文件路径

// 组件内代码
const [meds, setMeds] = useState<DocumentData[]>([]);

// 用useEffect触发数据获取
useEffect(() => {
    const fetchDocuments = async () => {
        try {
            const docs = await getMeds();
            setMeds(docs); // 此时docs必然是DocumentData[],无需额外处理undefined
        } catch (error) {
            console.error("获取药物数据失败:", error);
        }
    };

    fetchDocuments();
}, []);

进阶:自定义药物类型(推荐)

如果不想直接用泛化的DocumentData,可以定义自己的药物类型,让类型检查更精准:

// 定义符合业务需求的药物类型
interface Medication {
    id?: string;
    name: string;
    dosage: string;
    frequency: string;
    // 添加你实际用到的字段
}

// 修改getMeds的返回类型,同时带上文档ID(如果需要)
export const getMeds = async (): Promise<Medication[]> => {
    try {
        const user = auth.currentUser;
        if (user) {
            const snapshot = await getDocs(collection(db, "Users", user.uid, "Medications"));
            return snapshot.docs.map(doc => ({
                ...doc.data() as Medication,
                id: doc.id
            }));
        }
        return [];
    } catch (err: any) {
        throw new Error(err.message);
    }
}

// 组件内useState使用自定义类型
const [meds, setMeds] = useState<Medication[]>([]);

完成以上步骤后,就可以安全地对meds进行map操作生成React组件:

return (
    <div className="med-list">
        {meds.map(med => (
            <div key={med.id} className="med-item">
                <h3>{med.name}</h3>
                <p>剂量:{med.dosage}</p>
            </div>
        ))}
    </div>
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 21:35:03