简体   繁体   中英

How to access a key from an object using a mapped value that it is not recognized by typescript?

I have a data structure that looks like as follow:

     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
          }
        },
.......................

which is repeated for multiple 'data' object keys. I am trying to get both the key from data (categories such as returned and rejected) as well as the count key from meta which is in the same object key (category) inside 'data'. I managed to get the categories which are the 'data' keys but I am struggling to find a dynamic way to get the count key from meta for the same data key (category).

I did as follow:

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}

The issue is now that if I map categories and I want to use data.category TypeScript is complaining as Property 'category' does not exist on type 'StatisticsResponse'. But at the end it is just the categories names described below in my type. Category is the result of mapping the categories which are inside the StatisticResponse model. How can I handle/solve this in a dynamic way? I also need to be sure that when I pass category to the mapped component the count is associated to the right category.

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

  • Your categoriesArray is just an array of strings
  • category doesn't exist on type 'StatisticsResponse', but console.log(data.data[category]) will work.

You can better approach it as follow

useEffect(() => {
  const categoriesArray = Objects.keys(data.data).map(key => {
    return {
      key,
      data: data.data[key]
    }
  })
  setCategories(categoriesArray);
})

return (
  ...
  categories.map(category => {
    return (
      <Link to={{
        pathname: `/payouts/${category.key}`,
        state: { category: category.data }
      }}>
      </Link>
    )
  })
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM