如何解决useFetch Hook中never[]无法赋值给T的TypeScript错误?
如何解决useFetch Hook中useState初始化的类型错误?
需求
希望useFetch自定义Hook能够接受任意类型的数组作为data的类型。
现有代码
hooks/useFetch.ts
const useFetch = <T extends any[]>(dataUrl: string) => { const [data, setData] = useState<T>([]); const [error, setError] = useState<string | null>(null); const result = await axios(dataUrl); setData(result.data); }
说明:result类型为AxiosResponse<any, any>,成功返回的result.data应为对象数组。
App.tsx
interface City { rank: number; city: string; state: string; population: string; } const { data: cities, error } = useFetch<City[]>('/data.json');
错误信息
在代码行const [data, setData] = useState<T>([]);处出现如下错误:
Argument of type 'never[]' is not assignable to parameter of type 'T | (() => T)'.
解决方案
1. 直接给初始值添加类型断言
因为T被约束为任意数组类型,但空数组[]的默认类型是never[],无法直接匹配T。可以通过类型断言告诉TypeScript该空数组符合T的类型要求:
const [data, setData] = useState<T>([] as T);
2. 调整泛型设计(更严谨的方案)
把泛型定义为数组元素的类型,而非整个数组类型,这样初始值的类型逻辑会更清晰,同时修复原代码中await使用的错误:
import { useState, useEffect } from 'react'; import axios from 'axios'; const useFetch = <T>(dataUrl: string) => { const [data, setData] = useState<T[]>([]); const [error, setError] = useState<string | null>(null); useEffect(() => { const fetchData = async () => { try { const result = await axios(dataUrl); setData(result.data as T[]); } catch (err) { setError(err instanceof Error ? err.message : '请求发生未知错误'); } }; fetchData(); }, [dataUrl]); return { data, error }; };
此时使用Hook时只需传入数组元素的类型即可:
const { data: cities, error } = useFetch<City>('/data.json');
额外注意
原代码还有两处隐性问题需要修正:
await必须在async函数内使用,因此要把请求逻辑包裹在async函数中,并结合useEffect执行(自定义Hook顶层不能是async函数)- Hook需要返回
data和error,否则组件无法通过解构获取这些值
内容的提问来源于stack exchange,提问作者wyc
相关产品推荐
相关产品推荐

