1

TypeScript & React newbie here. Why does TypeScript not yell at me for constructor(foo: string) input type not matching {foo: string}? (Note: one of them is a string, the other an object.)

TypeScript will happily compile this, and of course the resulting code will blow up. I tried to turn on all the options tsconfig.json has to offer. I'm using typescript 2.5.3.

Is there any way, like typescript config, code change, or anything else to harden the code to avoid this? Any ideas appreciated, my goal is to write stable code.

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

class App extends React.Component<{ foo: string }, { foo: string }> {
    // expects string
    constructor(foo: string) {
        super();
        this.state = {
            foo: foo
        }
    }
    render() {
        return <div>{this.state.foo}</div>
    }
}

// Passes object { foo: string }
ReactDOM.render(<App foo="foo" />, document.getElementById('root'))

EDIT: simplified question

4
  • 1
    You do realize that this is not typescript, right? Commented Oct 10, 2017 at 20:42
  • @Amit, now that you say, I do, but I didn't realize at the time of asking. Thanks. So, then, any idea for a proper workflow for going JSX -> TS -> JS? Commented Oct 10, 2017 at 20:54
  • No, personally, I dislike react precisely for this reason. I find this syntax awkward and distracting. Commented Oct 10, 2017 at 20:57
  • @Amit, I'm looking for anything stable, so your suggestion of dropping TSX is in fact an improvement, thanks! Personally, I'd prefer to keep it if there is a way. Commented Oct 10, 2017 at 21:02

2 Answers 2

1
+50

You'll get the compiler complaints you're looking for if you remember to pass the props to super(). This is just part of extending React.Component, and should always be done.

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

I wanted to give you a bounty, but apparently I can only do so after 23hrs. Documenting it here, to avoid further answers.
0

Your concern :

// WRONG, to work, it should be:
//   constructor(props Props) {
constructor(foo: string, bar: string) {
  super();
}

is invalid because you can always inherit a class and provide your own constructor :

class A {
  constructor(a: number) { }
}

class B extends A {
  // ALLOWED
  constructor(b: string) {
    super(123)
  }
}

1 Comment

Thanks for the answer. Actually, that's not my problem. It's that the constructor type mismatches that of the call ReactDOM.render(<App foo="foo" bar="bar" />, root), which passes one object, not 2 strings.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.