获取 Typescript 错误:类型 'any[]' 不可分配给类型 'never[]'。 TS2345

时间:2020-12-19 01:02:45

标签: javascript reactjs typescript

我不确定为什么会收到此错误。 Type 'any[]' is not assignable to type 'never[]'. TS2345 这是我的代码。它在抱怨合并的数组。

  const [allInfo, setAllInfo] = useState([]);

  useEffect(() => {
    async function fetchData() {
      const validatorResponse = await axios.get(validatorEndpoint);
      const validatorIps = [];
      for (let i = 0; i < validatorResponse.data.count; i += 1) {
        const ipAddress = validatorResponse.data.results[i].ip_address;
        validatorIps.push({query: ipAddress});
      }
      const resultBatch = await axios.post(ipInfoEndpoint, validatorIps);
      const merged = [];
      for (let i = 0; i < validatorResponse.data.results.length; i += 1) {
        merged.push({
          ...validatorResponse.data.results[i],
          ...resultBatch.data[i],
        });
      }
      console.log(merged);
      setAllInfo(merged);
    }
    fetchData();
  }, []);

这是返回错误的行 -

setAllInfo(merged);

我试过了

const result : string[] = [];

以及常量

[allInfo, setAllInfo] = useState([] as any);

3 个答案:

答案 0 :(得分:1)

在使用 Typescript 和 React 时,给你的 state 一个接口来严格输入它是一种常见的模式,否则 Typescript 编译器会推断它。虽然对于许多其他类型的推断是可行的,但大多数情况下对于数组则行不通,因为假设空数组的最安全类型是 never[]

所有这些都是说,当您创建一个分配给变量的数组时,最好严格使用接口或自定义类型来键入该数组。

https://www.typescriptlang.org/docs/handbook/interfaces.html

所以你的代码通常看起来更像这样:

interface Foo {
  ...
}
...

const [allInfo, setAllInfo] = useState<Foo[]>([]);

const fetchData = async (): Promise<void> => {
  const { 
    data: {
     results = []
    } = {} 
  } = await axios.get(validatorEndpoint);
  const validatorIps = results.map(({ ip_address }) => ({query: id_address}));
  const { data = [] } = await axios.post(ipInfoEndpoint, validatorIps);

  const merged = results.map((result, i) => ({
    ...result,
    ...data[i]
  });

 setAllInfo(merged)
}

useEffect(() => {
  fetchData();
}, []);

我是使用我掌握的信息输入的,但将来您还应该为 fetchData 内的 API 响应提供类型,否则您将因依赖推理而遇到更多类型问题。

最后一件事,fetchData 中的 useEffect 违反了 React 的 exhaustive-deps linter 规则。在这种情况下,这不是什么大问题,但 fetchData 确实应该在 useEffect 内或使用 useCallback 钩子定义。

答案 1 :(得分:0)

您可以修复错误,为 merged 提供比推断的类型 (never[]) 更好的类型。

const merged: any[] = []; 应该足够了,但我建议您考虑更好的类型。

您还可以使用 Array.prototype.map 方法帮助打字稿推断类型,当您想创建新数组时,通常最好使用 .map,其中每个元素都从原始数组转换而来。

const merged = validatorResponse.data.results.map((result, i) => ({
   ...result,
   ...resultBatch.data[i],
})

答案 2 :(得分:0)

使用默认值以防止将来出现类型错误,尽量使用真实类型,不要使用任何类似类型

const [allInfo, setAllInfo] = useState<Array<typed>>([]);

const fetchData = async (): Promise<void> => {
  const { 
    data: {
     results = []
    } = {} 
  } = await axios.get(validatorEndpoint);
  const validatorIps = results.map(({ ip_address}) => ({query: id_address}));

  const { data = []}= await axios.post(ipInfoEndpoint, validatorIps);
  const merged = results.map((result, i) => ({
    ...result,
    ...data[i]
  });
 setAllInfo(merged)
}

useEffect(() => {
  fetchData();
}, []);

`