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

如何用TypeScript为泛型req函数实现正确的类型推断?

解决方案:泛型req函数的类型精确推断

你的核心问题在于路径参数path的类型没有和泛型K绑定,导致TypeScript无法精确推断参数和返回类型。以下是修正后的实现:

// 假设已定义基础类型
type Book = { id: number; title: string };
type Author = { id: number; name: string };

interface ValidQueries{
    books: (q: {
        limit?: number;
        category?: string;
    }) => Book[];

    authors: (q: {
        name?: string;
    }) => Author[];
}

// 修正后的req函数
const req = <K extends keyof ValidQueries>(path: K, params: Parameters<ValidQueries[K]>[0]) => {
    return useQuery([path, params], ({ queryKey }) => {
        const [, params] = queryKey;
        return httpRequest(path, params) as Promise<ReturnType<ValidQueries[K]>>;
    });
};

关键修改说明

  1. 绑定路径与泛型类型
    把path的类型从string改为K,这样当你传入具体路径(如"books")时,TypeScript会自动将泛型K推断为对应的键值,而非模糊的keyof ValidQueries联合类型。

  2. 精确参数类型推断
    此时Parameters<ValidQueries[K]>[0]会精准指向对应路径函数的第一个参数类型:

    • 传入"books"时,参数类型为{ limit?: number; category?: string; }
    • 传入"authors"时,参数类型为{ name?: string; }
  3. 返回类型精确化
    由于K是具体的键,ReturnType<ValidQueries[K]>会直接返回对应函数的返回类型(如Book[]或Author[]),而非联合类型。useQuery会基于这个类型自动推断最终返回的查询结果类型。

验证示例

// 调用示例1:参数自动提示limit/category,返回类型为UseQueryResult<Book[]>
const booksQuery = req("books", { limit: 10 });

// 调用示例2:参数仅允许name字段,返回类型为UseQueryResult<Author[]>
const authorsQuery = req("authors", { name: "J.K. Rowling" });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 15:40:37