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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:13:57