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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 09:33:31