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

如何封装useSWR Hook并实现正确的响应类型推导?

useSWR封装后类型推导失效的原因与解决方案

问题原因分析

你的封装方式存在两个核心问题,导致TypeScript无法正确推导fetcher的响应类型:

  1. 参数传递方式错误:原useSWR接收的是分散的rest参数,但你直接将args数组作为单个参数传入useSWR(args),这相当于把整个参数元组当作useSWR的第一个key参数,完全不符合原函数的调用签名。
  2. 泛型关联丢失:useSWR本身是泛型函数,依赖<Data, Error>两个泛型参数关联key、fetcher和返回值类型。而你的封装没有显式声明并传递这些泛型,导致Parameters<typeof useSWR>实际上是基于useSWR<any, any>生成的参数类型,丢失了泛型之间的关联关系。

正确的封装方式

要保留原useSWR的类型推导能力,需要显式声明泛型参数,并通过扩展运算符正确传递参数:

import useSWR from 'swr';

// 显式声明与原useSWR对齐的泛型参数
const useMySWR = <Data = any, Error = any>(
  ...args: Parameters<typeof useSWR<Data, Error>>
) => {
  // 使用扩展运算符分散传递参数,匹配原函数调用签名
  return useSWR<Data, Error>(...args);
};

验证类型推导

使用封装后的hook时,TypeScript会自动根据fetcher的返回值推导Data类型:

// 示例fetcher,返回值类型为{ name: string }
const fetcher = async (url: string) => {
  const res = await fetch(url);
  return res.json() as { name: string };
};

// data的类型会被自动推断为 { name: string } | undefined
const { data } = useMySWR('/api/user', fetcher);

深层原理解析

  • 泛型参数的显式传递是关键:原useSWR的参数类型(比如fetcher的类型)依赖<Data, Error>泛型,只有在封装函数上声明相同的泛型,并传递给Parameters<typeof useSWR<Data, Error>>,才能让TypeScript建立起参数与返回值之间的类型关联。
  • 扩展运算符的作用:...args将元组类型的参数分散传递,完全匹配原useSWR的调用签名(useSWR(key, fetcher, options)),而不是把数组当作单个参数传入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 11:47:37