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

TypeScript中Axios后端数据类型、错误类型及代码优化问询

重置密码代码问题解答与优化

1. 表单提交函数的参数e类型声明是否正确?

正确。React.FormEvent<HTMLFormElement>准确描述了表单提交事件的类型,事件目标是HTMLFormElement,preventDefault()方法也属于该类型的标准方法,完全适配表单提交场景。

2. catch块错误的理想类型是什么?

不要用any,推荐用**AxiosError | Error**(需从axios导入AxiosError类型),或者更精确的AxiosError<{ message?: string }>来捕获Axios请求的错误细节。如果用unknown作为兜底类型,再通过类型守卫判断错误类型,能更安全地处理不同场景:

  • Axios错误可获取响应体中的自定义错误信息(如error.response?.data.message)
  • 原生Error可获取错误栈或基础描述信息

3. 后端返回JSON数据的类型声明

应在函数外部定义语义化的接口/类型,避免内部重复声明,示例如下:

interface ResetPasswordResponse {
  message: string;
  success: boolean;
}

之后在Axios请求时通过泛型指定,让response.data自动推导为该类型,无需手动断言:

const response = await axios.post<ResetPasswordResponse>('/api/resetpassword', {...});

4. 代码优化方案

从结构扁平化、类型安全、错误精细化处理、可读性几个方向优化:

  • 提前退出:密码不匹配时直接提示并return,去掉else嵌套,让代码更扁平
  • 外部定义类型:把响应类型、表单信息类型移到函数外,提升复用性和可读性
  • 利用Axios泛型:自动推导响应数据类型,减少类型断言
  • 精细化错误处理:区分Axios错误和原生错误,展示更具体的错误信息
  • 增加表单信息类型约束:避免info对象属性类型混乱
  • 可选:添加loading状态,防止用户重复提交

优化后的完整代码

import { AxiosError } from 'axios';
import { useState } from 'react';
import { toast } from 'react-toastify';
import { useRouter } from 'next/router';

// 定义后端响应类型
interface ResetPasswordResponse {
  message: string;
  success: boolean;
}

// 定义表单输入信息的类型
interface ResetPasswordFormInfo {
  token: string;
  password: string;
  confirm_password: string;
}

const ResetPasswordPage = () => {
  const [info, setInfo] = useState<ResetPasswordFormInfo>({
    token: '',
    password: '',
    confirm_password: ''
  });
  const [isLoading, setIsLoading] = useState(false);
  const router = useRouter();

  const handleResetPassword = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    if (isLoading) return; // 防止重复提交

    // 密码校验不通过,直接退出
    if (info.password !== info.confirm_password) {
      toast.error("密码不匹配");
      return;
    }

    setIsLoading(true);
    try {
      const response = await axios.post<ResetPasswordResponse>('/api/resetpassword', {
        token: info.token,
        password: info.password
      });

      const { success, message } = response.data;
      if (success) {
        toast.success(message);
        router.push('/login');
      } else {
        toast.error(message);
      }
    } catch (error: unknown) {
      let errorMessage = "发生未知错误,请稍后重试";
      if (error instanceof AxiosError) {
        // 优先取后端返回的错误信息
        errorMessage = error.response?.data?.message || "重置密码失败,请检查链接或稍后重试";
      }
      toast.error(errorMessage);
    } finally {
      setIsLoading(false); // 无论成功失败都重置loading状态
    }
  };

  return (
    <form onSubmit={handleResetPassword}>
      {/* 省略表单输入元素 */}
      <button type="submit" disabled={isLoading}>
        {isLoading ? "重置中..." : "重置密码"}
      </button>
    </form>
  );
};

export default ResetPasswordPage;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 21:08:17