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

React中为异步获取JSON的箭头函数加类型标注遇错求助

修复TypeScript嵌套JSON类型标注与状态赋值错误

问题背景

我尝试为一个获取JSON文件的异步函数添加TypeScript类型标注,JSON返回多层嵌套结构,不想逐个定义嵌套对象类型,于是声明了如下类型:

type Dictionary = {
  menu: Record<string, unknown>;
  pages: Record<string, unknown>;
  result: Record<string, unknown>;
};

对应的函数实现如下:

const getData = async (lang: string): Promise<Dictionary> => {
  const path = `src/assets/file${lang}.json`;
  try {
    const response = await fetch(path);
    if (!response.ok) {
      throw new Error(`Some error`);
    }
    const data = await response.json();
    setDict(data.menu);
  } catch (error) {
    if (error) setError(error);
  }
};
useEffect(() => {
  getData(lang);
}, []);

运行后出现以下类型错误:

  • Unsafe assignment of an any value.
  • Unsafe argument of type any assigned to a parameter of type SetStateAction<null>
  • Unsafe member access .menu on an any value.
  • Argument of type '{}' is not assignable to parameter of type 'SetStateAction'.
  • Type '{}' provides no match for the signature '(prevState: null): null'.

错误原因解析

  1. response.json()类型缺失:该方法默认返回any类型,TypeScript无法识别data结构,导致访问data.menu和赋值给setDict时触发类型不安全提示。
  2. 函数返回值与声明不匹配:getData声明返回Promise<Dictionary>,但内部无return语句,违反类型约定。
  3. 状态类型不兼容:setDict对应的状态初始值为null,但未将Record<string, unknown>纳入状态类型,无法接收data.menu的值。
  4. 错误处理类型问题:catch块中的error是unknown类型,直接赋值给setError会触发类型不兼容错误。

修复步骤

1. 为解析后的JSON添加类型断言

明确告知TypeScript解析后的JSON符合Dictionary类型,消除any类型带来的不安全提示:

const data = await response.json() as Dictionary;

2. 修正函数返回类型

如果函数不需要返回数据,将返回类型改为Promise<void>,避免类型声明与实际行为不符:

const getData = async (lang: string): Promise<void> => {
  // 原有逻辑
};

3. 对齐状态变量类型

修改setDict对应的useState声明,让状态类型包含Record<string, unknown>和null:

const [dict, setDict] = useState<Record<string, unknown> | null>(null);

4. 规范错误处理类型

先判断error的实际类型,再赋值给setError,同时给错误状态指定正确类型:

// 声明错误状态
const [error, setError] = useState<Error | null>(null);

// 在catch块中处理
catch (err) {
  if (err instanceof Error) {
    setError(err);
  } else {
    setError(new Error(String(err)));
  }
}

5. 补充useEffect依赖项

将lang添加到useEffect的依赖数组中,避免React的依赖缺失警告:

useEffect(() => {
  getData(lang);
}, [lang]);

完整修复代码

import { useEffect, useState } from 'react';

type Dictionary = {
  menu: Record<string, unknown>;
  pages: Record<string, unknown>;
  result: Record<string, unknown>;
};

const YourComponent = ({ lang }: { lang: string }) => {
  const [dict, setDict] = useState<Record<string, unknown> | null>(null);
  const [error, setError] = useState<Error | null>(null);

  const getData = async (lang: string): Promise<void> => {
    const path = `src/assets/file${lang}.json`;
    try {
      const response = await fetch(path);
      if (!response.ok) {
        throw new Error(`请求失败,状态码:${response.status}`);
      }
      const data = await response.json() as Dictionary;
      setDict(data.menu);
    } catch (err) {
      if (err instanceof Error) {
        setError(err);
      } else {
        setError(new Error('未知错误'));
      }
    }
  };

  useEffect(() => {
    getData(lang);
  }, [lang]);

  return (
    <div>
      {error && <p>错误提示:{error.message}</p>}
      {/* 组件其他内容 */}
    </div>
  );
};

export default YourComponent;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 12:43:29