Roman
Roman

Reputation: 21757

Type 'Element[]' is missing the following properties from type 'Element': type, props, key

I have the standard arrow map ES7 function with Typescript and React environment:

 const getItemList: Function = (groups: any[]): JSX.Element => 
  group.map((item: any, i: number) => {
    const itemCardElemProps = { handleEvents: () => {}, ...item}
    return <Item key={`${item.id}_${i}`} {...itemCardElemProps} />
  })

and get the error:

TS2739: Type 'Element[]' is missing the following properties from type 'Element': type, props, key

Version: typescript 3.5.3

Upvotes: 88

Views: 142474

Answers (7)

DesperateEngineer
DesperateEngineer

Reputation: 121

I was getting the same error using this code:

let expensesContent = <p>No expenses found.</p>;

if (filteredExpenses.length > 0) {
    expensesContent = filteredExpenses.map((expense) => (<ExpenseItem expense={expense} key={expense.id} />));
}

The fix was to change the first line to:

let expensesContent: JSX.Element[] = [(<p>No expenses found.</p>)];

Upvotes: 1

Simran Singh
Simran Singh

Reputation: 2859

You need to change the type of the function output from JSX.Element to ReactNode[] like this:

import { ReactNode } from 'react'

const getItemList: Function = (groups: any[]): ReactNode[] => 
    groups.map((item: any, i: number) => {
    const itemCardElemProps = { key: item.id, handleEvents: () => {}, 
     ...item}
    return <Item {...itemCardElemProps} />
})

Upvotes: -1

Roman
Roman

Reputation: 21757

To fix the error, it is necessary to change type of the function output from JSX.Element to React.ReactElement[] or JSX.Element[] like this:

 const getItemList: Function = (groups: any[]): React.ReactElement[] => 
  groups.map((item: any, i: number) => {
    const itemCardElemProps = { key: item.id, handleEvents: () => {}, ...item}
    return <Item {...itemCardElemProps} />
  })

or you can rewrite it in the interface style:

interface IGetItemList {
  (groups: any[]): React.ReactElement[] // or JSX.Element[]
}

const getItemList: IGetItemList = groups =>
  groups.map((item: any, i: number) => {
    const itemCardElemProps = { key: item.id, handleEvents: () => {}, ...item }
    return <Item {...itemCardElemProps} />
  })

Upvotes: 45

Gass
Gass

Reputation: 9344

I had an issue related to this error that may happen to other people. I'm new to TS and had the bad habit of using [ and ] to open and close the return JSX. As I just discovered TS doesn't allow it. So they should be replaced by ( )

enter image description here

Upvotes: -1

Mohammad Atiour Islam
Mohammad Atiour Islam

Reputation: 5708

I was getting the error because of I am inheriting JSX.Element but I was using the .ts file extension. when I use the .tsx file extension my problem resolve.

enter image description here

Upvotes: 8

andrewmart.in
andrewmart.in

Reputation: 1703

You could always just send back a single JSX.Element as a fragment, too:

interface IOptions {
   options: string[]
}

const CardArray: React.FC<IOptions> = ({ options }) => {
   return <>{options.map(opt => opt)}</>
}

This way you're matching the returned type and it won't affect your markup.

Upvotes: 89

Akios Dev
Akios Dev

Reputation: 163

@Roman They must have changed something, this doesn't work for me

code:

const CardArray = (props: Items): JSX.Element[] => {
    return props.items.map((item) => <Item data={item} />);
};

export default CardArray;

error:

JSX element type 'Element[]' is not a constructor function for JSX elements.
Type 'Element[]' is missing the following properties from type 'Element': type, props, key

edit: nevermind, I just had to add the function type, to the function... kind of stupid if you ask me.

what worked me:

const CardArray: Function = (props: Items): JSX.Element[] => {
    return props.items.map((item) => <Item data={item} />);
};

Upvotes: 15

Related Questions