如何用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]>>; }); };
关键修改说明
绑定路径与泛型类型
把path的类型从string改为K,这样当你传入具体路径(如"books")时,TypeScript会自动将泛型K推断为对应的键值,而非模糊的keyof ValidQueries联合类型。精确参数类型推断
此时Parameters<ValidQueries[K]>[0]会精准指向对应路径函数的第一个参数类型:- 传入
"books"时,参数类型为{ limit?: number; category?: string; } - 传入
"authors"时,参数类型为{ name?: string; }
- 传入
返回类型精确化
由于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
相关产品推荐
相关产品推荐

