Home > Software design >  How to fix React TypeScript error: Argument of type '""' is not assignable to pa
How to fix React TypeScript error: Argument of type '""' is not assignable to pa

Time:11-20

I am working on a React app that was pulled from a live server and I'm trying to run it locally. When I start it up I get this error:

Argument of type '""' is not assignable to parameter of type 'SetStateAction'. TS2345

75 |               onClick={(): void => {
76 |                 if (regulatoryListActiveId === key) {
77 |                   setregulatoryListActiveId("");
   |                                             ^
78 |                 } else {
79 |                   setregulatoryListActiveId(key);
80 |                 }

Here is my code:

/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
import React, { useState } from "react";

const ChemicalRegulatoryListFilter = (props: any) => {
  const {
    chemicalRegulatoryList,
    setChemicalRegulatoryList,
    noOfRegulatoryListSelected,
    setNoOfRegulatoryListSelected,
    errorMessage,
    setErrorMessage,
    selectedValues,
    setSelectedValues,
    setIsSearchClicked,
  } = props;
  const [regulatoryListActiveId, setregulatoryListActiveId] = useState();

  const toggleRegulatoryListItem = (
    parentIndex: number,
    childIndex: number
  ) => {
    const regulatoryList = [...chemicalRegulatoryList];
    const isSelected =
      regulatoryList[parentIndex].subItems[childIndex].selected;
    if (!isSelected) {
      if (noOfRegulatoryListSelected === 10) {
        const error = { ...errorMessage, showMaxLimitMessage: true };
        setErrorMessage(error);
        return;
      }
      regulatoryList[parentIndex].selected = true;
      regulatoryList[parentIndex].noOfSelected  = 1;
      setNoOfRegulatoryListSelected(noOfRegulatoryListSelected   1);
      selectedValues.push({
        name: "regulatory",
        itemLabel: regulatoryList[parentIndex].itemLabel,
        itemValue: regulatoryList[parentIndex].itemValue,
        noOfSelected: regulatoryList[parentIndex].noOfSelected,
        parentIndex,
        childIndex,
        subItemsItemLabel:
          regulatoryList[parentIndex].subItems[childIndex].itemLabel,
        subItemsItemValue:
          regulatoryList[parentIndex].subItems[childIndex].itemValue,
      });
    } else {
      regulatoryList[parentIndex].noOfSelected -= 1;
      setNoOfRegulatoryListSelected(noOfRegulatoryListSelected - 1);
      const error = { ...errorMessage, showMaxLimitMessage: false };
      setErrorMessage(error);
      const newSelectedValues = selectedValues.filter((obj: any) => {
        return (
          obj.subItemsItemValue !==
          regulatoryList[parentIndex].subItems[childIndex].itemValue
        );
      });
      setSelectedValues(newSelectedValues);
    }
    regulatoryList[parentIndex].subItems[childIndex].selected = !isSelected;
    setChemicalRegulatoryList(regulatoryList);
  };

  if (chemicalRegulatoryList !== undefined) {
    return (
      <div className="chemical-toxicity-filter">
        <div className="title">REGULATORY LISTS</div>
        <ul className="filter">
          {chemicalRegulatoryList.map((item: any, key: number) => (
            <li
              key={`item-${key}`}
              className={`${
                regulatoryListActiveId !== key ? "collapsed" : ""
              } ${item.noOfSelected > 0 ? "selected" : ""}`}
              onClick={(): void => {
                if (regulatoryListActiveId === key) {
                  setregulatoryListActiveId("");
                } else {
                  setregulatoryListActiveId(key);
                }
              }}
            >
              {item.itemLabel}
              <ul>
                {item.subItems.map((subItem: any, innerKey: number) => (
                  <li
                    key={`item-${innerKey}`}
                    className={`${subItem.selected ? "selected" : ""}`}
                    onClick={(e): void => {
                      setIsSearchClicked(false);
                      e.stopPropagation();
                      toggleRegulatoryListItem(key, innerKey);
                    }}
                  >
                    {subItem.itemLabel}
                  </li>
                ))}
              </ul>
            </li>
          ))}
        </ul>
      </div>
    );
  }
  return <></>;
};
export default ChemicalRegulatoryListFilter;

After reading similar questions on stackoverflow I have tried changing this:
const [regulatoryListActiveId, setregulatoryListActiveId] = useState();
to this:
const [regulatoryListActiveId, setregulatoryListActiveId] = useState<string>(); That seems to fix the initial error but then this error happens:

This condition will always return 'true' since the types 'string | undefined' and 'number' have no overlap. TS2367

72 |               key={`item-${key}`}
73 |               className={`${
74 |                 regulatoryListActiveId !== key ? "collapsed" : ""
   |                 ^
75 |               } ${item.noOfSelected > 0 ? "selected" : ""}`}
76 |               onClick={(): void => {
77 |                 if (regulatoryListActiveId === key) {

Anyone know how solve this? Thanks!

CodePudding user response:

It looks like you want the state value to be a number, since you're doing:

setregulatoryListActiveId(key);

and key is the index of the element being iterated over.

Including undefined in the type might cause a bit of unnecessary confusion too - if I were you, I'd change the definition to:

const [regulatoryListActiveId, setregulatoryListActiveId] = useState(-1);

and change

setregulatoryListActiveId("");

to

setregulatoryListActiveId(-1);

to clear it (since no array index will be equal to -1).

You also might consider following the typical naming conventions with camelCase - perhaps setregulatoryListActiveId should be called setRegulatoryListActiveId, as most readers of the code would expect.

  • Related