'Typescript error (2345) when pushing element to array of elements(React js)
I'm pretty new to Typescript and I was trying to migrate a component I had on Reactjs to typescript. This component is supposed to receive a number from 0-10 as a prop and according to that number populate an array with stars components which are icons I imported from React icons. once the array is populated is then rendered by the component. but when I try to push those elements to the Array typescript throws an error as if those elements were not of type Element neither Jsx. The only way I found it to work was by setting
let starsArray: Element[] | any = [];
but my idea was not to leave anything as "any" type;
import React, { useState, useEffect } from "react";
import { BsStarFill } from "react-icons/bs";
interface PropsInterface {
stars: number;
big?: boolean;
}
const Stars: React.FC<PropsInterface> = ({ stars, big }) => {
const [array, setArray] = useState<Element[]>([]);
useEffect(() => {
let starsArray: Element[] = [];
let starsAmount: number = Math.round(stars) / 2; //gets rating from props and turns it into integer divided by two (ratings were 1-10 and we needed 1-5 stars);
for (let i = 0; i < 5; i++) {
//goes throught 1-5 and if the rating amount is higher or equal on each iteration it pushes a filled star component to starsArray, else it pushes an empty star
if (starsAmount > i) {
starsArray.push(<BsStarFill className="star--filled" key={i} />);
} else {
starsArray.push(<BsStarFill className="star--unfilled" key={i} />);
}
}
setArray(starsArray);
}, []);
return (
<div className={big ? "stars --bigstars" : "stars"}>
{Object.values(array).map((each) => each)}
</div>
);
};
export default Stars;
these where the lines showing the error with a red underline
(<BsStarFill className="star--unfilled" key={i} />)
(<BsStarFill className="star--filled" key={i} />)
these is the complete error :
Argument of type 'JSX.Element' is not assignable to parameter of type 'Element'. Type 'ReactElement<any, any>' is missing the following properties from type 'Element': attributes, classList, className, clientHeight, and 123 more.ts(2345)
I would really appreciate some help here, thank you !
Solution 1:[1]
UPDATE: After trying different solutions I found myself fixing the error by setting array and StarsArray as an array of ReactNodes type;
Starsarray: ReactNode[] = [];
A more general explanation: TypeScript expects you to explicitly define the type of the array elements. The array elements type you declared must match the type TypeScript expects to see. Here is a simple example:
interface ISomething {
arr: string[]
}
// Somewhere in a class a method uses ISomething interface.
public someMethod(): ISomething['arr'] {
// Note, if you omit ": ISomething['arr']" in the line below
// you would face ts2345 error when you push a string into the array later.
const localArray: ISomething['arr'] = [];
localArray.push('somestring');
return localArray;
}
Solution 2:[2]
So the compiler is saying that <BsStarFill />
is a JSX.Element. But you have declared the array and star arrays as Element[]
which is a differnt type
let starsArray: JSX.Element[] = [];
const [array, setArray] = useState<JSX.Element[]>([]);
change these to the proper types and it should compile
When to use JSX.Element vs ReactNode vs ReactElement?
this contains more information about jsx element and react element types
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Valentine Shi |
Solution 2 | Shaynel |