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

如何在TypeScript中动态访问对象映射键并获取对应值?

问题描述

我有如下数据结构:

data: {
  returned: {
    items: {
      payment_returned: {
        count: randFloat(),
        percentage: randFloat()
      }
    },
    meta: {
      count: 1000,
      percentage: 1000
    }
  },
  rejected: {
    items: {
      external_validation_failed: {
        count: randFloat(),
        percentage: randFloat()
      },
      missing_capability: {
        count: randFloat(),
        percentage: randFloat()
      },
      payment_request_cancelled: {
        count: randFloat(),
        percentage: randFloat()
      },
      validation_schema_failed: {
        count: randFloat(),
        percentage: randFloat()
      },
      conversion_to_v1_failed: {
        count: randFloat(),
        percentage: randFloat()
      }
    },
    meta: {
      count: 1000,
      percentage: 1000
    }
  },
  // ...其他类似结构的键
}

该结构在data对象的多个键下重复。我需要同时获取data的键(如returned、rejected这类类别),以及对应类别下meta.count的值。目前已成功拿到类别列表,但动态获取对应meta.count时遇到TypeScript报错。

我的实现代码:

const WidgetCategories = () => {
  const { data, isLoading, isSuccess } = useGetStatisticsDataQuery();
  const [categories, setCategories] = useState<PayoutState[]>();
  useEffect(() => {
    if (data) {
      const categoriesArray = Object.keys(data.data);
      setCategories(categoriesArray as unknown as PayoutState[]);
    }
  }, [isSuccess, data]);
  return (
    <>
      <div className="w-68 cursor-pointer rounded-lg bg-white p-4 shadow-plain-lg">
        <p className="mb-8 text-sm font-bold">Payouts states</p>
        {isSuccess && categories
          ? categories.map((category: PayoutState) => {
              console.log(data.category);
              return (
                <Link
                  className="align-center mb-2 ml-4 flex cursor-pointer text-sm font-medium"
                  to="/payouts/:category"
                  key={category}
                >
                  <PayoutBadge type={category} count={9} />
                </Link>
              );
            })
          : null}
    </>
  );
};

当前问题:映射categories时使用data.category触发TypeScript错误:Property 'category' does not exist on type 'StatisticsResponse',但category确实是StatisticsResponse中data的合法键。同时需要确保count值与对应类别正确关联并传递给组件。

对应的类型定义:

export interface StatisticsResponse {
  data: {
    returned: ItemsData;
    rejected: ItemsData;
    completed: ItemsData;
    action_required: ItemsData;
    pending: ItemsData;
    processing: ItemsData;
    received: ItemsData;
  };
}
解决方案

1. 正确动态取值

TypeScript报错是因为.操作符只能访问类型上明确声明的属性,动态键需要使用方括号语法。将data.category改为data.data[category]即可获取对应类别的数据,再提取meta.count:

const categoryData = data.data[category];
const count = categoryData.meta.count;

2. 强化类型安全

为让TypeScript识别category是data的合法键,先定义一个类型来获取StatisticsResponse['data']的键:

type PayoutState = keyof StatisticsResponse['data'];

这样就无需as unknown as PayoutState[]这种强制类型转换,直接将Object.keys(data.data)转为PayoutState[]更安全:

const categoriesArray = Object.keys(data.data) as PayoutState[];

3. 简化组件逻辑

无需用useState存储categories,直接在渲染阶段处理即可,减少不必要的状态更新:

const WidgetCategories = () => {
  const { data, isLoading, isSuccess } = useGetStatisticsDataQuery();

  if (isLoading) return <div>加载中...</div>;
  if (!isSuccess || !data) return null;

  const categories = Object.keys(data.data) as PayoutState[];

  return (
    <div className="w-68 cursor-pointer rounded-lg bg-white p-4 shadow-plain-lg">
      <p className="mb-8 text-sm font-bold">Payouts states</p>
      {categories.map((category) => {
        const count = data.data[category].meta.count;
        return (
          <Link
            className="align-center mb-2 ml-4 flex cursor-pointer text-sm font-medium"
            to={`/payouts/${category}`}
            key={category}
          >
            <PayoutBadge type={category} count={count} />
          </Link>
        );
      })}
    </div>
  );
};

4. 修复路由参数问题

原代码中to="/payouts/:category"是硬编码的占位符,需用模板字符串替换为实际的category值:to={/payouts/${category}},确保跳转后路由显示正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 07:15:35