Displaying an array received from Usestate hook with Typescript

38,170

You error is this line

const [portfolioData, setPortfoloioData] = useState<IProject[] | []>([]);

portfolioData become union type of IProject[] | []. In this case it is useless and leads to error. Any variable of type IProject[] can hold empty array. So it is no need to create union of array of type IProject and array of type any (square braces without type are considered of type any).

To correct errors just do

const [portfolioData, setPortfoloioData] = useState<IProject[]>([]);

And if you want to dig into details why this happens, I recommend to read this (it best describes the issue) and this.

Share:
38,170
Brian Gwaltney
Author by

Brian Gwaltney

Updated on July 08, 2020

Comments

  • Brian Gwaltney
    Brian Gwaltney almost 4 years

    I am trying to display an array of information using map that is received from the usestate hook. When writing the map function, I get a "Cannot invoke an expression whose type lacks a call signature." Error. If I create a function that returns the same information and call that function, I do not get the error.

        export default function Portfolio() {
          const [portfolioData, setPortfoloioData] = useState<IProject[] | []>([])
    
          useEffect(() => {
            const portfolio: IProject[] = getPortfolio()
            setPortfoloioData(portfolio)
          }, [])
    
    //Function to display the map that works.
          const displayBlocks = (portfolioData: IProject[]): JSX.Element[] => {
            return portfolioData.map((item, index) =>
              <ProjectBlock key={index} project={item} index={index} />
            )
          }
    
          return (
            <div className='text-center pt-3'>
              <h1 className='pb-4'>Portfolio</h1>
    
    //This works without error
              {displayBlocks(portfolioData)} 
    
    //This shows the missing call signature error even though
    //it is the same as what is returned by the displayBlocks function.
              {portfolioData.map((item, index) =>
                <ProjectBlock key={index} project={item} index={index} />
              )}
            </div>
          )
        }
    

    I would like to figure out how to display the information with a simple map within the return section without having to call another function. What am I doing wrong?