如何在 React 应用程序中使用 axios 响应解决 TypeScript 错误

Pet*_*ner 6 typescript reactjs

我有以下 React 函数(使用 React Hooks 的 alpha)有一个 TypeScript 错误(认为它仍然有效)。错误指向 axios 承诺以 .then(a=>{setData(a)) 完成的代码行......我认为这是对 a 的抱怨。

TS2345:类型为“void”的参数 | AxiosResponse' 不可分配给类型为 'SetStateAction' 的参数。“void”类型不能分配给“SetStateAction”类型。

这是代码的链接:https : //codesandbox.io/s/7zyx4vv6k6

在这个文件中应该输入更多内容吗?我是 TypeScript 的新手,很惊讶我只需要做很少的事情就可以让它只抱怨这一件事。在 codeandbox 中,它没有显示我可以看到的 tpyescript 错误。有没有办法让它像在我的 webstorm IDE 中那样显示在那里?在代码沙盒中,我想让类型正确的行是 32,即使它没有在代码沙盒中显示为错误

import { useState, useEffect } from "react";
import axios from "axios";

const useAxiosFetch = (url: string, timeout: number) => {
  const [data, setData] = useState(null);
  const [error, setError] = useState(false);
  const [errorMessage, setErrorMessage] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    let unmounted = false;
    let source = axios.CancelToken.source();
    axios
      .get(url, {
        cancelToken: source.token,
        timeout: timeout,
      })
      .catch(function(e) {
        if (!unmounted) {
          setError(true);
          setErrorMessage(e.message);
          setLoading(false);
          if (axios.isCancel(e)) {
            console.log(`request cancelled:${e.message}`);
          } else {
            console.log("another error happened:" + e.message);
          }
        }
      })
      .then(a => {
        if (!unmounted) {
          setData(a);
          setLoading(false);
        }
      });
    return function() {
      unmounted = true;
      source.cancel("Cancelling in cleanup");
    };
  }, []);

  return { data, loading, error, errorMessage };
};

export default useAxiosFetch;
Run Code Online (Sandbox Code Playgroud)

Kar*_*ski 11

原因在这一行:

const [data, setData] = useState(null)
Run Code Online (Sandbox Code Playgroud)

因为没有为 显式提供类型参数useState,TypeScriptdata根据初始状态的类型推断 的类型。在这种情况下,初始状态是null并且 TypeScript 将此类型视为唯一可能的状态。

您知道状态将是null或其他东西 - 但 TypeScript 不会。让我们使用类型参数来告诉它到底发生了什么。

const [data, setData] = useState<AxiosResponse | null | void>(null);
Run Code Online (Sandbox Code Playgroud)

这消除了错误,但看起来很奇怪——为什么会void这样?原因是你catch在你之前then——并且由于catch发出副作用(void换句话说,返回),传播到的类型catchvoidor AxiosResponse。让我们通过替换then和来解决这个问题catch

最终的解决方案:

const [data, setData] = useState(null)
Run Code Online (Sandbox Code Playgroud)