0
votes

I'm trying to convert an application to React with typescript. I had it running correctly in plain ES2015. But now that I've added typescript to the picture, gulp throws errors when trying to compile my .tsx file:

error TS2339: Property 'setState' does not exist on type 'App'.

Even a stripped down test component fails with:

error TS2605: JSX element type 'App' is not a constructor function for JSX elements.
  Type 'App' is missing the following properties from type 'ElementClass': context, setState, forceUpdate, props, refs
import * as React from "../libs/noinject/react.development";
import * as ReactDOM from "../libs/noinject/react-dom.development";

interface State {foo: string}
export class App extends React.Component<{}, State> {
  state: State
  constructor(props: any) {
    super(props);
    this.state = {
      foo: 'bar',
    };
  }
  render() {
    return (
      <div>
        {this.state.foo}
      </div>
    );
  }
}

document.addEventListener('DOMContentLoaded', function () {
  ReactDOM.render(<App />, document.getElementById('app-root'));
});

Clearly, the typescript compiler is not recognising the React.Component type. I am using gulp-typescript to compile, with the following compiler options:

{
    'lib': ['ES2018', 'DOM'],
    'target': 'es6',
    'module': 'none',
    'moduleResolution': 'node',
    'jsx': 'react',
    'types': [
      'react',
      'react-dom',
    ],
  }

node modules @types/react and @types/react-dom are installed and clearly being used, since removing them immediately causes the TS compilation step to fail complaining about the types not being found.

Note that I also get the squiggly red underline in vscode intellisense with the same error (Type 'App' is missing the following properties...).

What gives?

2
Can you try change your typescript.json/option to modules:"commonjs" and not "none"?Han
I've tried 'commonjs' and 'ES6' - no dice :(see sharper

2 Answers

1
votes

I got your setup to work by adding a tsconfig.json to the root directory with the following contents:

{
  "compilerOptions": {
    "noImplicitAny": true,
    "lib": ["es6", "dom"],
    "target": "es6",
    "module": "commonjs",
    "moduleResolution": "node",
    "jsx": "react",
    "types": [
      "react",
      "react-dom"
    ]
  },
  "exclude": ["node_modules"]
}

Then, in the gulpfile.js, I had the following:

var gulp = require('gulp');
var ts = require('gulp-typescript');
var project = ts.createProject('./tsconfig.json');

gulp.task('default', function () {
    return gulp.src('./index.tsx')
        .pipe(project())
        .pipe(gulp.dest("dist/"));
});

Testing with gulp-typescript and the other code and packages you said you had, I was able to get this to compile and create an index.js file in the dist/ folder.

0
votes

So the problem was I was importing React from the .js file, when I needed just to import "react" which typescript 2+ knows how to find inside the node_modules/@types. In other words, the lines:

import * as React from "../libs/noinject/react.development";
import * as ReactDOM from "../libs/noinject/react-dom.development";

should be:

import * as React from "react";
import * as ReactDOM from "react-dom";