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

React+TypeScript useEffect场景下get函数多返回类型赋值报错如何解决

报错原因

你定义的get函数返回值类型是Promise<IProduct[]> | Promise<IUser>的联合类型,TypeScript 无法自动识别本次调用具体返回哪种类型,因此和setProduct要求的IProduct[]类型不匹配,抛出类型错误。

解决方案

方案1(推荐):将get函数改造为泛型实现

从根源上优化通用请求函数的类型适配,所有调用场景都可以灵活指定返回类型:

// 修改类型定义为泛型
export type TGet = <T>(path: string) => Promise<T>

// 函数实现适配泛型
export const get: TGet = <T>(path: string): Promise<T> => {
    return fetch("https://" + window.location.hostname + ":4001/" + path, {
        method: "GET",
        credentials: "include",
        mode: "cors",
        headers: {
            "Content-Type": "application/json"
        }
    }).then(r => r.json() as Promise<T>);
};

调用时指定对应泛型参数即可:

useEffect(() => {
    // 调用时指定返回类型为IProduct[]
    get<IProduct[]>(`api/fixture/products/${match.params.id}`).then((productData) => {
        setProduct(productData); // 类型自动匹配,无报错
    });
}, [match.params.id]);

方案2(快速修复):调用时手动类型断言

如果不想改动原有get函数的定义,直接在赋值前手动断言类型即可:

useEffect(() => {
    get(`api/fixture/products/${match.params.id}`).then((productData) => {
        setProduct(productData as IProduct[]); // 手动告知TS该值为IProduct[]类型
    });
}, [match.params.id]);

方案3(运行时校验):添加类型守卫

如果需要同时做运行时数据合法性校验,可以添加类型守卫收窄类型:

// 定义IProduct[]的类型守卫,根据实际IProduct的字段调整判断逻辑
function isProductList(data: IProduct[] | IUser): data is IProduct[] {
    return Array.isArray(data) && data.every(item => typeof item === 'object' && 'id' in item && 'price' in item);
}

// 调用时先做类型判断
useEffect(() => {
    get(`api/fixture/products/${match.params.id}`).then((productData) => {
        if (isProductList(productData)) {
            setProduct(productData); // TS自动识别类型为IProduct[]
        }
    });
}, [match.params.id]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 08:39:03