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

如何收窄类型解决TS2339:类型'Error|TypeWithData'不存在属性'data'?

问题根因

你的getCsrfToken函数当前的返回值类型为 Promise<CSRFToken | Error>,可选链操作符?.仅能识别并收窄undefined/null类型,无法区分联合类型中都不为空的CSRFToken和Error类型,所以你在调用函数后直接读取.data属性时,TS无法确认当前值不是Error实例,就会抛出该警告。
另外你当前的写法还有一个逻辑漏洞:axios本身在请求返回4xx/5xx状态码时会直接抛出异常,你没有捕获这部分异常,现在写的返回Error的逻辑仅能覆盖「请求成功但响应无data」的场景,请求失败的场景会直接走Promise.reject,不会触发你写的返回逻辑。

推荐解决方案(符合async函数常规设计)

直接把返回Error改为抛出错误,这样函数返回值类型会变成Promise<CSRFToken>,不存在联合类型的问题,上层调用时统一用try/catch处理所有错误场景即可:

const getCsrfToken = async () => {
  const csrfTokenResponse = await axios.get<any, AxiosResponse<CSRFToken>>(csrfUrl);
  if (csrfTokenResponse?.data) {
    return csrfTokenResponse.data;
  }
  throw new Error('Failed to fetch CSRF token.');
};

调用示例:

try {
  const csrfToken = await getCsrfToken();
  // 直接使用csrfToken,类型已经是CSRFToken
  console.log(csrfToken.data);
} catch (e) {
  // 处理所有错误逻辑,包括请求失败、无data两种场景
  console.error((e as Error).message);
}

可选方案(坚持返回Error的场景)

如果你确实不想用throw抛错,需要上层通过返回值判断是否出错,就需要在读取属性前先通过instanceof做类型收窄:

const tokenOrError = await getCsrfToken();
if (tokenOrError instanceof Error) {
  // 处理错误
  console.error(tokenOrError.message);
} else {
  // 此处TS自动收窄类型为CSRFToken,读取data不会报错
  console.log(tokenOrError.data);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 12:27:00