TypeScript非函数组件类型复用与自定义Hook类型重构方法咨询
核心重构方案
1. 抽取公共类型消除重复签名
你已经定义了参数接口GetDataArgs,可以进一步把重复的函数签名抽为独立的类型别名,同时将options的any替换为原生RequestInit类型(浏览器fetch方法第二个参数的标准类型),比any类型更安全:
// 公共请求函数类型,多处可直接复用 type GetDataFunction = (url: string, options?: RequestInit) => Promise<void>;
后续无论是Hook返回值声明里的getData,还是内部定义的getAllData,都可以直接复用这个类型,不需要重复写参数和返回值签名。
2. 抽取Hook返回值类型
把useFetch的返回值也抽为独立接口,避免内联类型冗长难维护,同时增加泛型支持解决data为any的类型不安全问题:
import { Dispatch, SetStateAction } from 'react'; interface UseFetchReturn<T = unknown> { data: T | null; getData: GetDataFunction; fetchError: boolean; setData: Dispatch<SetStateAction<T | null>>; // 可补充你代码注释里提到的loading状态 loading: boolean; }
优化后完整代码
import { useState, Dispatch, SetStateAction } from 'react'; type GetDataFunction = <T = unknown>(url: string, options?: RequestInit) => Promise<T>; interface UseFetchReturn<T = unknown> { data: T | null; getData: GetDataFunction; fetchError: boolean; setData: Dispatch<SetStateAction<T | null>>; loading: boolean; } export const useFetch = <T = unknown>(): UseFetchReturn<T> => { const [data, setData] = useState<T | null>(null); const [fetchError, setFetchError] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false); const getAllData: GetDataFunction = async (url, options) => { try { setLoading(true); setFetchError(false); const res = await fetch(url, options); const result = await res.json() as T; setData(result); return result; } catch (e) { setFetchError(true); console.error(e); throw e; } finally { setLoading(false); } }; return { data, getData: getAllData, fetchError, setData, loading }; };
附加优化说明
- 补充了
loading状态,适配你代码中的注释需求,可直接用于渲染加载态UI - 每次请求前重置错误状态,避免上一次请求的错误结果影响下一次请求的状态判断
- 增加泛型支持,使用时可指定返回数据的类型,获得完整类型提示:
// 使用示例 const { data, loading } = useFetch<{ id: number; name: string }>(); // 此时data自动推导类型为 { id: number; name: string } | null
内容的提问来源于stack exchange,提问作者user8758206
相关产品推荐
相关产品推荐

