How to properly import React JSX from separate file in Typescript 1.6

bleslie404 picture bleslie404 · Oct 31, 2015 · Viewed 10.8k times · Source

I have the following app.tsx file working fine loading an App element from a React.Component and a child Worklist element from another React.Component (both classes defined in the same app.tsx file). This is running in Visual Studio with Typescript 1.6 installed (ECMAScript version: ECMAScript 5, JSX compilation: React, Module System: CommonJS).

However, I would like to split these two components into separate files. However, when I uncomment the import of WorkList and remove the class definition for the WorkList component from app.tsx - it fails with an error:

Error TS2604 JSX element type 'WorkList' does not have any construct or call signatures.

Here is the working app.tsx and the desired worklist.tsx.

// app.tsx
import * as React from "react";
import * as ReactDOM  from "react-dom";
//import * as WorkList from "./worklist";

interface Props {
    foo: string;
}

class WorkList extends React.Component<Props, {}> {
    constructor(props: Props) {
        super(props);
    }
    render() {
        return <h2>WorkList!{this.props.foo} </h2>
    }
}
class App extends React.Component<Props, {}> {
    constructor(props: Props) {
        super(props);
    }
    public render() {
        return <WorkList foo="baz"></WorkList>
    }
}


ReactDOM.render(    
    React.createElement(App, { foo: 'bar' }),
    document.getElementById('app')
);




//worklist.tsx
import * as React from "react";

interface Props {
    foo: string;
}

class WorkList extends React.Component<Props, {}> {
    constructor(props: Props) {
        super(props);
    }
    render() {
        return <h2>WorkList!{this.props.foo} </h2>
    }
}

<WorkList foo="bar" />

What is the proper way to import a child JSX with Typescript 1.6?

Here is the working code with the correct answer applied:

// app.tsx
import * as React from "react";
import * as ReactDOM  from "react-dom";
import WorkList from "./worklist";

interface Props {
    foo: string;
}

class App extends React.Component<Props, {}> {
    constructor(props: Props) {
        super(props);
    }
    public render() {
        return <WorkList foo="baz"></WorkList>
    }
}       
ReactDOM.render(

    React.createElement(App, { foo: 'bar' }),
    document.getElementById('app')
);

//worklist.tsx
import * as React from "react";

interface Props {
    foo: string;
}

export default class WorkList extends React.Component<Props, {}> {
    constructor(props: Props) {
        super(props);
    }
    render() {
        return <h2>WorkList!{this.props.foo} </h2>
    }
}

Answer

FlorianTopf picture FlorianTopf · Nov 1, 2015

I expect, that you need to properly export WorkList class in the worklist.tsx file, e.g. as default export:

export default class WorkList extend React.Component<Props, {}>

and then import it in app.tsx:

import WorkList from "worklist"

This should solve your problem.