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

如何在前端根据请求成功状态为response.data添加正确TypeScript类型?

为Auth请求函数添加正确TypeScript类型标注的解决方案

问题背景

存在一个无法修改的API认证路由,返回结构如下:

  • 认证成功时,返回AuthSuccess类型:
interface AuthSuccess {
  token: string
  user: object
}
  • 认证失败时,错误响应返回AuthError类型:
interface AuthError {
  error: string
}

基于Next.js使用Axios编写的请求函数如下:

const auth = ({email, password}) =>
  api // api是axios.create()的返回值
    .post(url, {email, password})
    .then((result) => ({
      success: true,
      data: response.data // 原代码笔误:应为result.data
    }))
    .catch((error) => ({
      success: false,
      data: error.response?.data // 此处应为AuthError类型
    }))

调用时,即便校验res.success,TypeScript仍无法正确推断data的类型:

const res = await auth(data)

if (res.success) {
  // 期望data为AuthSuccess,但TypeScript认为可能是两种类型
} else {
  // 期望data为AuthError,但TypeScript认为可能是两种类型
}

解决方案

使用判别式联合类型(Discriminated Union),让TypeScript能通过success字段自动缩小类型范围。

步骤1:定义完整的类型结构

首先明确请求参数类型,以及包含判别字段的结果类型:

// 请求参数类型
interface AuthProps {
  email: string;
  password: string;
}

// 成功结果类型(带判别式success: true)
type AuthSuccessResult = {
  success: true;
  data: AuthSuccess;
};

// 失败结果类型(带判别式success: false)
type AuthErrorResult = {
  success: false;
  data: AuthError;
};

// 联合结果类型
type AuthResult = AuthSuccessResult | AuthErrorResult;

步骤2:为Auth函数添加正确的类型标注

将函数改为async/await写法(更直观),并标注返回类型为Promise<AuthResult>,同时修正原代码笔误,对错误响应数据添加类型断言:

const auth = async ({ email, password }: AuthProps): Promise<AuthResult> => {
  try {
    const result = await api.post(url, { email, password });
    return {
      success: true,
      data: result.data
    };
  } catch (error) {
    // Axios无法自动推断error.response.data的类型,需手动断言
    return {
      success: false,
      data: error.response?.data as AuthError
    };
  }
};

步骤3:调用时的类型推断

此时调用函数,TypeScript会自动根据success的值推断data的类型:

const res = await auth(data);

if (res.success) {
  // res.data 自动推断为AuthSuccess类型
  console.log(res.data.token);
} else {
  // res.data 自动推断为AuthError类型
  console.log(res.data.error);
}

为什么之前的方案无效

  1. 方案1:返回Promise<AuthSuccess | AuthError>的问题在于,这两个类型没有共同的success判别字段,TypeScript无法通过条件判断缩小类型范围。
  2. 方案2:条件泛型AuthResult<T>需要在调用时明确指定泛型参数,但success的值是运行时动态决定的,无法提前确定,因此TypeScript无法正确推断类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 05:48:24