Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flow gives an error "Cannot assign [value] to this.[property] because property [property] is missing in [class]"

This works:

// @flow
import React, {Component} from 'react';


type Props = {};

class Delete extends Component<Props> {
  targetElement: null | winndow.HTMLInputElement;

  constructor(props: Props) {
    super(props);

    this.targetElement = null; // initialize to null
  }

  handleClick = (e: SyntheticEvent<> & {target: window.HTMLInputElement}) => {
    this.targetElement = (e.target: window.HTMLInputElement).value;
  };

  render() {
    return (
      <input onClick={this.handleClick} value="hello" />
    );
  }
}

export default Delete;

but this doesn't:

...
handleClick = (e: SyntheticEvent<> & {target: window.HTMLInputElement}) => {
    this.targetElement = e.target.value;
  };
...

The error message is: Cannot get e.target.value because property value is missing in EventTarget.

1) I've already typed the "target" property to be window.HTMLInputElement, which has a value property, so why does Flow insist that property value is missing in EventTarget (why EventTarget?)

In the first place, before I added Flow annotations, the code works great, and there were no console errors about missing properties.

I'm really confused as to how this works - I've read this and this, and it seems there are a huge range of workarounds/solutions, but I'm not sure why they work. Also, those are 2-3 years old, and I'm not sure if they're still relevant now. I'm new to Flow, but really interested to master it!

like image 727
Fabian Avatar asked May 25 '18 16:05

Fabian


1 Answers

Use SyntheticInputEvent<*>

  handleClick = (e: SyntheticInputEvent<*>) => {
    this.targetElement = e.target.value;
  };

or

  handleClick = (e: SyntheticEvent<HTMLInputElement>) => {
    this.targetElement = e.target.value;
  };

You might want to check the docs and also cheet sheets

like image 74
Tomasz Mularczyk Avatar answered Sep 23 '22 20:09

Tomasz Mularczyk