Reputation: 21757
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
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
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
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
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 (
)
Upvotes: -1
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.
Upvotes: 8
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
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