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
相关产品推荐
相关产品推荐

