TypeScript泛型fetch方法的接口定义优化方案咨询
嘿,我懂你现在的痛点——用那个递归的UnknownObject确实等于直接绕开了TypeScript的类型检查,完全浪费了它的优势;但每个端点写个专用fetch方法又会导致代码重复,太不优雅了。其实你想要的调用时动态指定返回类型的需求,用TypeScript的泛型就能完美解决,而且改动很小!
核心思路:把fetchJSON改成泛型函数
你只需要给fetchJSON添加一个泛型参数T,让它的返回值类型变成Promise<T>,这样调用的时候就能传入你期望的返回接口类型了。完全不需要那个UnknownObject接口,直接把它删掉就行。
修改后的完整代码
const fetchJSON = async <T>(url: string, body?: object): Promise<T> => { try { let response; if (!body) { response = await fetch(url); } else { response = await fetch(url, { method: "POST", headers: { Accept: "application/json", "Content-Type": "application/json" }, body: JSON.stringify(body) }); } // 新增:确保请求成功再解析,提升健壮性 if (!response.ok) { const errorData = await response.json() as T; if (response.status === 404) { return { ...errorData, error: 404 } as T; } throw new Error(`Request failed with status ${response.status}`); } const data = await response.json() as T; console.log(data); return data; } catch (err) { throw err; } }; export default fetchJSON;
调用方式(完全符合你的需求)
假设你已经定义了PageProps接口:
interface PageProps { title: string; content: string; // 其他业务字段... } // 调用时指定泛型类型,返回值自动推导为PageProps类型 const pageData = await fetchJSON<PageProps>("pageurl"); // 此时pageData会有完整的类型提示,比如pageData.title会被识别为string类型
如果是POST请求,同样可以轻松指定返回类型:
interface User { id: number; name: string; avatar: string; } const userData = await fetchJSON<User>("/api/user", { userId: 123 });
额外优化:通用错误结构(可选)
如果你的后端返回的错误有统一结构(比如所有接口都可能返回error字段),可以定义一个基础接口让泛型T继承,让类型检查更严谨:
interface BaseResponse { error?: number | string; } // 修改泛型约束,确保所有返回类型都包含基础错误字段 const fetchJSON = async <T extends BaseResponse>(url: string, body?: object): Promise<T> => { // ... 内部代码不变 };
这样调用时,T会自动包含error字段的类型提示,不用手动在每个业务接口里重复定义了。
内容的提问来源于stack exchange,提问作者josias
相关产品推荐
相关产品推荐

