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

TypeScript自定义API错误处理Hook报错:'doRequest'不存在于'any[]'类型

问题分析与解决方案

核心错误原因

你的useRequest Hook返回的是数组[doRequest, errors],但在SignUp组件中错误地使用了对象解构语法{doRequest, errors},TypeScript识别到返回值是数组类型,自然找不到对象属性doRequest,因此抛出该错误。

完整修正方案

1. 修正组件的解构方式

将SignUp组件中的对象解构改为数组解构:

// 原错误代码
const {doRequest, errors} = useRequest(...);

// 修正后
const [doRequest, errors] = useRequest({
    url: '/api/users/signup',
    method: 'post',
    body: { email, password }
});

2. 完善Hook的类型定义(解决潜在类型问题)

除了核心错误,你的Hook还存在一些类型不严谨的地方,以下是优化后的完整Hook代码:

import axios, { AxiosError } from 'axios';
import { useState } from 'react';

// 限制请求方法为axios支持的类型,避免任意字符串
type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch';

interface UseRequestParams {
    method: HttpMethod;
    body: Record<string, unknown>; // 用更通用的对象类型替代object
    url: string;
}

// 后端返回的错误项类型(根据实际响应调整)
interface ApiErrorItem {
    message: string;
}

// 后端错误响应结构
interface ApiErrorResponse {
    errors: ApiErrorItem[];
}

const useRequest = ({ url, method, body }: UseRequestParams) => {
    // 明确errors的类型:React元素或null
    const [errors, setErrors] = useState<JSX.Element | null>(null);

    const doRequest = async () => {
        try {
            setErrors(null); // 请求前清空错误
            const response = await axios[method](url, body);
            return response.data;
        } catch (err) {
            // 断言错误为AxiosError,获取正确的响应结构
            const axiosErr = err as AxiosError<ApiErrorResponse>;
            setErrors(
                <div className="alert alert-danger">
                    <h4>Oooops.....</h4>
                    <ul className="m-0">
                        {axiosErr.response?.data.errors.map((e) => (
                            <li key={e.message}>{e.message}</li>
                        ))}
                    </ul>
                </div>
            );
            return null;
        }
    };

    return [doRequest, errors] as const; // 使用as const让TypeScript推断精确的数组类型
};

export default useRequest;

3. 组件的其他小优化

可以给表单事件参数加上正确的类型,避免{ preventDefault: () => void }的模糊定义:

const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    await doRequest();
};

关键优化点说明

  • 使用as const断言Hook的返回数组,让TypeScript能准确推断数组元素的类型,避免被视为any[]
  • 限制HTTP方法为固定枚举类型,防止传入axios不支持的方法
  • 明确错误状态的类型为React元素或null,避免类型模糊
  • 对axios错误进行类型断言,安全访问响应数据中的错误信息

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 14:17:38