Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using JS React component in TypeScript: JSX element type 'MyComponent' is not a constructor function for JSX elements

I'm working with a JavaScript legacy project which uses React framework. We have there some React component defined which I'd like to re-use in a totally different TypeScript React project.

The JS React component is defined in controls.jsx file and looks as follows:

export class MyComponent extends React.Component {
  render() {
    return <h1>Hi from MyComponent! Message provided: {this.props.message}</h1>;
  }
}

In my TypeScript React project I'm trying to use it like that:

import * as React from "react";
import * as ReactDOM from "react-dom";
import { MyComponent } from "../JavaScriptProject/controls";

ReactDOM.render(
  <MyComponent message="some nice message"/>,
    document.getElementById("documents-tree")
);

but I'm getting the following error: enter image description here

Error messages say:

JSX element type 'MyComponent' is not a constructor function for JSX elements. Type 'MyComponent' is missing the following properties from type 'ElementClass': context, setState, forceUpdate, props, and 2 more.ts(2605) JSX element class does not support attributes because it does not have a 'props' property.ts(2607)

I've already tried the solution with custom typings file described in this question, but it changes nothing.

I understand that the JS component has some strongly-typed properties required by TypeScript missing, but in my tsconfig.json I have the allowJs set to true:

{
  "compilerOptions": {
    "allowJs": true,
    "baseUrl": ".",
    "experimentalDecorators": true,
    "jsx": "react",
    "noEmitOnError": true,
    "outDir": "lib",
    "sourceMap": true,
    "target": "es5",
    "lib": [
      "es2015",
      "dom"
    ]
  },
  "exclude": [
    "node_modules",
    "dist",
    "lib",
    "lib-amd"
  ]
}

so I hoped it should work...

Thanks for your help

like image 224
Dawid Sibiński Avatar asked Dec 17 '19 08:12

Dawid Sibiński


People also ask

What is JSX element in TypeScript?

JSX is an embeddable XML-like syntax. It is meant to be transformed into valid JavaScript, though the semantics of that transformation are implementation-specific.

Can not be used as a JSX component?

The error "Component cannot be used as a JSX component" occurs for multiple reasons: Returning an array of JSX elements instead of a single element. Returning any value other than a JSX element or null from a component. Having outdated version of React typings.

What are IntrinsicAttributes?

As for IntrinsicAttributes ? It is the type representing the props that all react components must accept (and fyi: there is only one such prop, key , an optional string | number ). If you are really stuck, perhaps consider asking a new question? – CRice.

Does not have any construct or call signatures?

The error "JSX element type does not have any construct or call signatures" occurs when we try to pass an element or a react component as props to another component but type the prop incorrectly. To solve the error, use the React. ElementType type.


1 Answers

You should turn allowSyntheticDefaultImports to true since React does not export default.

(source: https://github.com/facebook/react/blob/master/packages/react/index.js)

{
  "compilerOptions": {
    "allowJs": true,
    "baseUrl": ".",
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true, // turn on allowSyntheticDefaultImports
    "jsx": "react",
    "noEmitOnError": true,
    "outDir": "lib",
    "sourceMap": true,
    "target": "es5",
    "lib": [
      "es2015",
      "dom"
    ]
  },
  "exclude": [
    "node_modules",
    "dist",
    "lib",
    "lib-amd"
  ]
}

Also, you should add the shape for component props. For example, in your code:

export class MyComponent extends React.Component<{ message: string }> { ...
like image 60
Long Nguyen Duc Avatar answered Sep 30 '22 06:09

Long Nguyen Duc