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

修改变量属性时如何为其添加TypeScript类型标注?

解决TypeScript错误:'newExpenses'隐式具有'any'类型

问题根源

你在useMemo的第二个map里直接引用了还未完成初始化的newExpenses,导致TypeScript无法推断其类型,同时形成循环引用,触发7022错误。

修复步骤

1. 定义适配饼图的类型接口

先在文件顶部定义新类型,明确饼图所需字段:

import { Category } from "@/types";

// 新增:适配饼图的类型
type PieChartCategory = {
  id: string;
  name: string;
  value: number;
  color: string;
};

2. 重构useMemo逻辑,消除循环引用

把计算最大value的逻辑从第二个map中抽离,先处理排序后的中间数组,再基于该数组计算颜色,避免直接引用未初始化的newExpenses:

const newExpenses = useMemo<PieChartCategory[]>(() => {
  // 第一步:计算每个分类的总支出并排序
  const sortedCategories = categories
    .map((category) => ({
      id: category.name,
      name: category.name,
      value: Number(
        category.expenses
          .reduce((previous, current) => previous + current.price, 0)
          .toFixed(2)
      ),
    }))
    .sort((a, b) => a.value - b.value);

  // 第二步:计算最大value的位数,用于透明度计算
  const maxValue = sortedCategories[sortedCategories.length - 1]?.value || 0;
  const maxDigitLength = maxValue.toString().length;

  // 第三步:添加color属性
  return sortedCategories.map((category) => ({
    ...category,
    color: `rgba(64,224,208,${category.value / Math.pow(10, maxDigitLength)})`,
  }));
}, [categories]);

3. 给newExpenses添加类型注解

通过useMemo<PieChartCategory[]>明确返回值类型,让TypeScript完全知晓变量的类型结构。

完整修复后的核心代码片段

import DashboardBox from "@/components/DashboardBox";
import { useGetExpensesQuery, useGetCategoriesQuery } from "@/state/api";
import { useMemo } from "react";
import { Cell, Pie, PieChart, ResponsiveContainer, Tooltip } from "recharts";
import { Category } from "@/types";

type Props = {};
// 新增适配类型
type PieChartCategory = {
  id: string;
  name: string;
  value: number;
  color: string;
};

const Row1 = (props: Props) => {
  const { data: categories, isLoading } = useGetCategoriesQuery();

  if (!categories || isLoading) {
    return <p>Loading...</p>;
  }

  const newExpenses = useMemo<PieChartCategory[]>(() => {
    const sortedCategories = categories
      .map((category) => ({
        id: category.name,
        name: category.name,
        value: Number(
          category.expenses
            .reduce((previous, current) => previous + current.price, 0)
            .toFixed(2)
        ),
      }))
      .sort((a, b) => a.value - b.value);

    const maxValue = sortedCategories[sortedCategories.length - 1]?.value || 0;
    const maxDigitLength = maxValue.toString().length;

    return sortedCategories.map((category) => ({
      ...category,
      color: `rgba(64,224,208,${category.value / Math.pow(10, maxDigitLength)})`,
    }));
  }, [categories]);

  return (
    <>
      <DashboardBox gridArea="a">
        <ResponsiveContainer width="100%" height="100%">
          <PieChart width={400} height={400}>
            <Pie
              isAnimationActive={true}
              paddingAngle={5}
              innerRadius={60}
              outerRadius={80}
              label
              data={newExpenses}
              dataKey="value"
              cx="50%"
              cy="50%"
              fill="#12efc8"
            >
              {newExpenses.map((entry, index) => (
                <Cell key={`cell-${index}`} fill={entry.color} />
              ))}
            </Pie>
            <Tooltip />
          </PieChart>
        </ResponsiveContainer>
      </DashboardBox>
    </>
  );
};

export default Row1;

额外说明

  • 重构后消除了循环引用,TypeScript可正确推断类型
  • 明确的类型注解提升了代码可读性与可维护性
  • 抽离中间变量让逻辑更清晰,便于后续调整

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 15:05:00