React Hook泛型类型推断问题:默认回调返回类型与泛型冲突
React Hook泛型类型推断问题解决
问题代码
const useFetch = <ResponseType>( fetchInputFactory: () => RequestInfo | URL | [RequestInfo | URL, RequestInit], deps: DependencyList | undefined, transformResponse: (response: Response) => Promise<ResponseType> = async (response) => response ): | { loading: true } | { loading: false; success: true; response: ResponseType } | { loading: false; success: false; error: Error } => { // Hook实现逻辑 }
错误信息
(parameter) response: Response Type 'Promise<Response>' is not assignable to type 'Promise<ResponseType>'. Type 'Response' is not assignable to type 'ResponseType'. 'ResponseType' could be instantiated with an arbitrary type which could be unrelated to 'Response'.ts(2322) index.ts(6, 22): The expected type comes from the return type of this signature.
问题原因
错误出在transformResponse的默认值与泛型ResponseType的匹配上:你没有给ResponseType设置默认类型,当用户不传入自定义的transformResponse时,TypeScript认为ResponseType可以是任意类型,但默认函数返回的是Response类型,无法兼容任意类型,因此抛出类型错误。
解决方案
方案一:给泛型设置默认类型
给ResponseType指定默认类型为Response,同时对默认函数的返回值做类型断言,确保类型匹配:
import { DependencyList } from 'react'; const useFetch = <ResponseType = Response>( fetchInputFactory: () => RequestInfo | URL | [RequestInfo | URL, RequestInit], deps: DependencyList | undefined, transformResponse: (response: Response) => Promise<ResponseType> = async (response) => response as Promise<ResponseType> ): | { loading: true } | { loading: false; success: true; response: ResponseType } | { loading: false; success: false; error: Error } => { // 你的Hook实现逻辑 return { loading: true }; }
方案二:让TypeScript自动推断类型
将transformResponse设为可选参数,在内部处理默认逻辑,这样TypeScript会根据用户传入的transformResponse自动推断ResponseType:
import { DependencyList } from 'react'; const useFetch = <ResponseType = Response>( fetchInputFactory: () => RequestInfo | URL | [RequestInfo | URL, RequestInit], deps: DependencyList | undefined, transformResponse?: (response: Response) => Promise<ResponseType> ): | { loading: true } | { loading: false; success: true; response: ResponseType } | { loading: false; success: false; error: Error } => { // 内部处理默认转换逻辑 const handleTransform = transformResponse ?? (async (res) => res as unknown as ResponseType); // 你的Hook实现逻辑 return { loading: true }; }
两种方案都能解决类型错误,方案二更灵活,用户无需手动指定泛型类型,TypeScript会自动根据传入的transformResponse推断返回的response类型。
内容的提问来源于stack exchange,提问作者sdellysse
相关产品推荐
相关产品推荐

