Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Typescript: Argument of type '(i: string[]) => any[]' is not assignable to parameter of type 'string[]'

In my project, I am trying to add multiple emails as a chip. But I am facing a problem here, first time, when I paste multiple email values it gets inserted into the field, but second time when I copy some other values and paste them into the field, it replaces the previous values. to solve this added a line "setItem((i: string[]) => […i, …toBeAdded]);" inside "handlePaste". but this leads to another issue "Typescript: Argument of type ‘(i: string[]) => any[]’ is not assignable to parameter of type ‘string[]’."


type Props = {
  LabelName?: string;
  optional?: string;
  tooltip?: string;
  placeholder?: string;
  className?: string;
  upload?: boolean;
  items?: any;
  setItem: (items: string[]) => void;
};
const TagActions = (props: Props) => {
  // const [items, setItem] = useState<string[]>([]);
  const [value, setValue] = useState("");
  const [error, setError] = useState("");
  const divRef = useRef<HTMLDivElement>(null);
  const [flag, setFlag] = useState(false);

  const {
    LabelName,
    optional,
    tooltip,
    placeholder,
    className,
    upload,
    items,
    setItem,
  } = props;

  const handleDelete = (item: any) => {
    const result = items.filter((i: any) => i !== item);
    setItem(result);
  };

  const handleItemEdit = (item: any) => {
    const result = items.filter((i: any) => i !== item);
    setItem(result);
    setValue(item);
  };

  const handleKeyDown = (evt: any) => {
    if (["Enter", "Tab", ","].includes(evt.key)) {
      evt.preventDefault();

      const test = value.trim();

      if (test && isValid(test)) {
        items.push(test);
        setValue("");
      }
    }
  };

  const isValid = (email: any) => {
    let error = null;

    if (isInList(email)) {
      error = `${email} has already been added.`;
    }

    if (!validator.isEmail(email)) {
      setFlag(true);
    }

    if (error) {
      setError(error);

      return false;
    }

    return true;
  };

  const isInList = (email: any) => {
    return items.includes(email);
  };

  const handleChange = (evt: any) => {
    setValue(evt.target.value);
  };

  const handlePaste = (evt: any) => {
    evt.preventDefault();

    const paste = evt.clipboardData.getData("text");
    const emails = paste.match(/[\w\d\\.-]+@[\w\d\\.-]+\.[\w\d\\.-]+/g);

    if (emails) {
      const toBeAdded = emails.filter((email: any) => !isInList(email));

      console.log("items inside", items);
      console.log("toBeAdded", toBeAdded);

      
      setItem((i: string[]) => [...i, ...toBeAdded]);
      console.log("items after", items);
    }
  };

  return (
    <>
      <div className="formSection">
        {LabelName && (
          <div className={`control-label ${styles.label}`}>
            <label>
              <span className={styles.alignLeft}>
                <span className={styles.labelText}>{LabelName}</span>
              </span>
            </label>

            <span className={styles.alignRight}>
              {upload && (
                <label htmlFor="uploadCSV">
                  <span className={styles.upload}>Upload CSV</span>
                </label>
              )}

              {optional && <span className={styles.light}>Optional</span>}

              {tooltip && (
                <span className={styles.tooltip_ic} title={tooltip}>
                  <FontAwesomeIcon icon={faCircleQuestion} size="xs" />
                </span>
              )}
            </span>
          </div>
        )}
        <input
          type="file"
          accept=".csv"
          style={{ display: "none" }}
          id="uploadCSV"
        />
        <div className={styles.inputGroup}>
          <TextField
            className={` textfield-emailchip test ${className}`}
            InputProps={{
              startAdornment: items.map(
                (
                  item:
                    | boolean
                    | Key
                    | ReactElement<any, string | JSXElementConstructor<any>>
                    | ReactFragment
                    | null
                    | undefined
                    | any
                    | string
                ) => (
                  <Chip
                    className={
                      !validator.isEmail(item)
                        ? styles.chipTagError
                        : styles.chipTag
                    }
                    key={item}
                    tabIndex={-1}
                    label={item}
                    onDelete={() => handleDelete(item)}
                    onClick={() => handleItemEdit(item)}
                    deleteIcon={<FontAwesomeIcon icon={faXmark} size="xs" />}
                  />
                )
              ),
            }}
            ref={divRef}
            value={value}
            placeholder={placeholder}
            onKeyDown={(e) => handleKeyDown(e)}
            onChange={(e) => handleChange(e)}
            onPaste={(e) => handlePaste(e)}
          />
        </div>

        {error && <p className="error">{error}</p>}
      </div>
    </>
  );
};

export default TagActions;


Please give me a solution to fix this problem.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

setItem is defined as having the type (items: string[]) => void. This definition means it is a function that accepts an array of strings, for example setItem(['a', 'b', 'c']) would be a valid invocation of a function with this type.

However, in the code setItem is then called differently, like this:

setItem((i: string[]) => [...i, ...toBeAdded]);

The argument (i: string[]) => [...i, ...toBeAdded] is not an array of strings; it is itself another function. TypeScript is saying this code is invalid because the argument given to setItem is a function, not an array of strings.

You can either change the invocation to pass an array of strings, or change the definition to say it’s supposed to accept a function, depending on which matches your true intent for the code.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading