TypeScript: JSX element type does not have any construct or call signatures TypeScript: JSX element type does not have any construct or call signatures reactjs reactjs

TypeScript: JSX element type does not have any construct or call signatures


You need to tell the compiler that the parameter is a constructor function and that returns a React component with the properties language and pathname

function withMoreInfo<T extends React.Component<{ language: string, pathname: string }, any>>(Wrapped: new (props: { language: string, pathname: string }, context?: any) => T) {    return class WithMoreInfo extends React.Component<{ asPath: string }> {        static async getInitialProps({ asPath }: { asPath: string }) {            return { asPath }        }        render() {            const { asPath } = this.props            const language = asPath.indexOf('/ro') === 0 ? 'ro' : 'en'            return <Wrapped language={language} pathname={asPath} />        }    }}// The component must have properties language and pathname and only thoseclass Home extends React.Component<{ language: string, pathname: string }> {    render() {        return <div />    }}export default withMoreInfo(Home)

In your original version when you invoke withMoreInfo(Home), T would have indeed been a react component, however you could have just as well invoked withMoreInfo(1) since T was in no way constrained. The generic function must be correct for any type that is passed to it, so the compiler considered T as being possibly anything and so it could reliably say nothing about it.The solution is to let the compiler know, that the Wrapped parameter is a constructor of a react component, namely any react component T that has as properties { language: string, pathname: string }. A constructor function has a similar signature declaration to a regular function, just with the new keyword, hence new (props: { language: string, pathname: string }, context?: any) => T


Putting an answer here because it is relevant to the error in general.

I was missing new inside the type definition.

some-js-component.d.ts file:

import * as React from "react";export default class SomeJSXComponent extends React.Component<any, any> {    new (props: any, context?: any)}

and inside the tsx file where I was trying to import the untyped component:

import SomeJSXComponent from 'some-js-component'...inside render()   return (        <React.Fragment>            <SomeJSXComponent withProps={asdf} />        </React.Fragment>   );