I'm working with React 16.2.0, TypeScript 2.7.1, and any is not allowed as a type.
The main component:
// index.js
import * as React from 'react'
import Page from './page'
import i18n from '../i18n'
import PageContent from '../components/pageContent'
import withMoreInfo from '../hoc/withMoreInfo'
class Home extends React.Component {
render () {
return <Page title={ i18n.t('home.title') }>
<PageContent />
</Page>
}
}
export default withMoreInfo(Home)
The hoc file:
import * as React from 'react'
export default function withMoreInfo<T> (Wrapped: 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 } />
}
}
}
I can't solve this error: error #TS2604: JSX element type 'Wrapped' does not have any construct or call signatures.
Any hint is very much appreciated. Thanks, Paul
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 those
class 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>
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With