Home > Net >  React typescript: How to pass array values
React typescript: How to pass array values

Time:10-05

I am trying to add a dropdown, in which the option elements were added into a separate file.

Store.js


export const consultationOptinList = {
  options: [
    {
      id: 1,
      label: "Preview Survey",
      action: () => navigate("/public-consultation-preview"),
      icon: "eye",
    },
    {
      id: 2,
      label: "Resend Survey",
      action: handleMenus,
      icon: "envelope",
    },
    {
      id: 3,
      label: "Update Respondents",
      action: handleMenus,
      icon: "comment-pen",
    },
],
}

Then this value is imported and added to the component.

content.tsx

import { consultationOptinList } from "FormContainer/store";
...
...

 <ListOptions
                  options={consultationOptinList.options}
                  className="dropdownBtn"
                  tab={tab}
 />

Inside the component props is defined like this

type Props = {
  ...
  options?: DropDown[];
  tab?: string;
  ...
};

DropDown type is defined like this.

export type DropDown = {
  id: number;
  action: () => void;
  label: string;

  icon: IconName;
};

But I am facing an issue

enter image description here

(property) options?: DropDown[] | undefined Type '{ id: number; label: string; action: any; icon: string; }[]' is not assignable to type 'DropDown[]'. Type '{ id: number; label: string; action: any; icon: string; }' is not assignable to type 'DropDown'. Types of property 'icon' are incompatible. Type 'string' is not assignable to type 'IconName'.ts(2322) index.tsx(29, 3): The expected type comes from property 'options' which is declared here on type 'IntrinsicAttributes & Props'

I am confused as to solve this error. Please give me some suggestions to fix this error.

CodePudding user response:

Assuming IconName is some sort of string union type, eg

type IconName = "eye" | "envelope" | "comment-pen";

One option is to properly define the options array where it is declared

import type { DropDown } from "somewhere";

interface ConsultationOptionList {
  options: DropDown[],
}

export const consultationOptinList: ConsultationOptionList = {
  //...
}

You could also try casting but that doesn't guarantee type safety

<ListOptions
  options={consultationOptinList.options as DropDown[]}
  className="dropdownBtn"
  tab={tab}
/>

CodePudding user response:

There could be two ways to resolve it,

First: If your IconName is an ENUM type, then rather than assigning strings, you would need to assign enum values.


// considering following enum type

enum IconName {
  eye = "eye",
  envelope = "envelope",
  commentPen = "comment-pen"
}

export const consultationOptinList = {
  options: [
    {
      id: 1,
      label: "Preview Survey",
      action: () => navigate("/public-consultation-preview"),
      icon: IconName.eye,
    },
    {
      id: 2,
      label: "Resend Survey",
      action: handleMenus,
      icon: IconName.envelope,
    },
    {
      id: 3,
      label: "Update Respondents",
      action: handleMenus,
      icon: IconName.commentPen,
    },
],
}

Second: If your IconName is defined with limited string values, you can assign type over the variable you are exporting, to avoid casting. (Sorry, I missed the part of file being a js for option, but if it can be defined as ts or moved to another ts file, this can work.)


type IconName = "eye" | "envelope" | "comment-pen";

export const consultationOptinList: {options: DropDown[]} = {
  options: [
    {
      id: 1,
      label: "Preview Survey",
      action: () => navigate("/public-consultation-preview"),
      icon: "eye",
    },
    ...
],
}

You could try any solution based on the definition of IconName.

  • Related