facebook/flow

Excessive typing for class-based React component

nick10032 opened this issue · 3 comments

Flow version: 0.186

//@flow
import * as React from 'react';

export default class App extends React.Component<{}> {
    onClick = (event: SyntheticEvent<HTMLButtonElement>) => {
        console.log(event);
    };

    render(): React.Node {
        return <button onClick={this.onClick}>test</button>
    }
}

Expected behavior

Flow should use signature of assigned function for onClick

Actual behavior

Cannot build a typed interface for this module. You should annotate the exports of this module with types. Missing type
annotation at property `onClick`: [signature-verification-failure]

Is this bug or expected behavior?

  • Link to Try-Flow or Github repo:

@nick10032 I think one way how to circumvent this issue is to type the class like this:

//@flow

import * as React from 'react';

export default class App extends React.Component<{}> {
  onClick: (SyntheticEvent<HTMLButtonElement>) => void = (event) => {
    console.log(event);
  };

  render(): React.Node {
    return <button onClick={this.onClick}>test</button>;
  }
}

@mrtnzlml Agreed, this also could be simplified with some generic types for better reusing

//@flow

import * as React from 'react';

// somewhere in types.js
type SyntheticEventHandler<T> = (SyntheticEvent<T>) => void;
type SyntheticInputEventHandler<T> = (SyntheticInputEvent<T>) => void;

export default class App extends React.Component<{}> {
  onClick: SyntheticEventHandler<HTMLButtonElement> = (event) => {
    console.log(event);
  };

  onChange: SyntheticInputEventHandler<HTMLInputElement> = (event) => {
     ...
  }

  render(): React.Node {
    return <button onClick={this.onClick}>test</button>;
  }
}

This is very common React component usage, yet I haven't seen recommendation like this in the docs.
If this is intended behavior and just a docs issue - it's fine, wondering why Flow wouldn't follow initial handler signature