Typescript – 'No overload matches this call' when using fetched data and material-ui

Issue

I practiced creating a dropdown menu with

  1. hardcoded array before trying to create a
  2. dropdown menu with an array retrieved with useSWR.

I used this for the first practice: https://codesandbox.io/s/76k0ft?file=/demo.tsx:1819-2045

Instead of using the hardcoded names variable,I saved a fetched array as shown:

const { data, error } = useSWR(
    "https://api.github.com/repos/vercel/swr",
    fetcher
);
if (error) return <h1>"An error has occurred."</h1>;
if (!data) return <h1>"Loading..."</h1>;
const arr = data.topics; 

I rendered it as shown:

{arr.map((tag,id)=> (
     <MenuItem
          key={id}
          value={tag}
     >
        {tag}
     </MenuItem>
))}

To which I was given red underlines for the parameter that says the following when cursor is placed over the tag and id parameters.

Parameter ‘tag’ implicitly has an ‘any’ type.ts(7006)

I clicked on the suggested Quick fixes and now the MenuItem and its props are underlined.

After Quick fixes it looks like this

{arr.map((tag: {} | null | undefined,id: React.Key | null | undefined)=> (
     <MenuItem
          key={id}
          value={tag}
     >
         {tag}
     </MenuItem>
))}

The message I get from hovering over the red underlines is

No overload matches this call. Overload 1 of 3, ‘(props: { href:
string; } & { autoFocus?: boolean | undefined; classes?:
Partial | undefined; dense?: boolean | undefined;
disabled?: boolean | undefined; disableGutters?: boolean | undefined;
divider?: boolean | undefined; selected?: boolean | undefined; sx?:
SxProps<…> | undefined; } & Omit<…> & CommonProps & Omit<…>):
Element’, gave the following error.
Type ‘{ children: {} | null | undefined; key: Key | null | undefined; value: {} | null | undefined; }’ is not assignable to type
‘IntrinsicAttributes & { href: string; } & { autoFocus?: boolean |
undefined; classes?: Partial | undefined; dense?:
boolean | undefined; … 4 more …; sx?: SxProps<…> | undefined; }
& Omit<…> & CommonProps & Omit<…>’.
Property ‘value’ does not exist on type ‘IntrinsicAttributes & { href: string; } & { autoFocus?: boolean | undefined; classes?:
Partial | undefined; dense?: boolean | undefined; …
4 more …; sx?: SxProps<…> | undefined; } & Omit<…> & CommonProps
& Omit<…>’. Overload 2 of 3, ‘(props: { component:
ElementType; } & { autoFocus?: boolean | undefined; classes?:
Partial | undefined; dense?: boolean | undefined; …
4 more …; sx?: SxProps<…> | undefined; } & Omit<…> & CommonProps
& Omit<…>): Element’, gave the following error.
Property ‘component’ is missing in type ‘{ children: {} | null | undefined; key: Key | null | undefined; value: {} | null | undefined;
}’ but required in type ‘{ component: ElementType; }’. Overload
3 of 3, ‘(props:
DefaultComponentProps<ExtendButtonBaseTypeMap<MenuItemTypeMap<{},
"li">>>): Element’, gave the following error.
Type ‘{} | null | undefined’ is not assignable to type ‘string | number | readonly string[] | undefined’.
Type ‘null’ is not assignable to type ‘string | number | readonly string[] | undefined’.ts(2769) OverridableComponent.d.ts(17,
7): ‘component’ is declared here. index.d.ts(2246, 9): The expected
type comes from property ‘value’ which is declared here on type
‘IntrinsicAttributes & { autoFocus?: boolean | undefined; classes?:
Partial | undefined; dense?: boolean | undefined; …
4 more …; sx?: SxProps<…> | undefined; } & Omit<…> & CommonProps
& Omit<…>’

What is the difference between mapping through a hardcoded array and an array fetched using useSRW? There were no red underline in the first example.

The code works, but I am trying to understand how Typescript works. I also get this warning message in the console:

react-dom.development.js:67 Warning: A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component.

Solution

The array listed in the sandbox is an array of string. Therefore mapping the individual element should give a string. Hope this helps.

{arr.map((tag:string,id:number)=> (
     <MenuItem
          key={id}
          value={tag}
     >
        {tag}
     </MenuItem>
))}

Answered By – Sathya

Answer Checked By – Terry (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.