Flow: Component` [1] with less than 1 type argument

Created on 25 Feb 2018  Â·  14Comments  Â·  Source: facebook/flow

bug:

I have a simple REACT 16 class that extends component.
It passes two properties className and 'disabled` (both are optional).
The ONLY error in the code is from Flow - The error above..
Components source code included below ...

//
// @flow
//
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

// Import Style
import styles from './styles.css';

class Button extends Component {
  static propTypes = {
    className: PropTypes.string,
    disabled: PropTypes.bool,
  };

  static defaultProps = {
    disabled: false,
  }

  // render a page title element
  render () {
    const {
      className,
      disabled,
      ...rest
    } = this.props;

    const classes = classNames(
      className,
      { [`${styles.disabled}`]: disabled }
    );

    return (
      <div className={classes} {...rest} >
        {this.props.children}
      </div>
    );
  }
}

export default Button;

Most helpful comment

well rip.

Explicitly type your props, kids.

All 14 comments

Check out the Flow docs on working with React components: https://flow.org/en/docs/react/components/

Instead of using prop-types, you can just declare a type alias and pass those props to your component with a generic:

import React, { Component } from 'react';

type Props = {
  className?: string,
  disabled?: boolean
};

class Button extends Component<Props> {
  static defaultProps = {
    disabled: false
  };
  ...
}

You can get rid of the ? if you want the properties to be required.

OK - so change a couple of 100 files in a project

The example on the link doesn't cover how you deal with shapes / OneOfTypes ......
nd swapping PropType node for any - seems like we would be losing something ....

i.e

myProp: PropTypes.oneOfType([
  PropTypes.arrayOf(PropTypes.node),
  PropTypes.node
]),

React.ChildrenArray allows a single or an array (nested to any level) of Nodes:

myProp: React.ChildrenArray<React.Node>

is there any way to suppress these warnings? just upgraded from 0.52.0 to 0.69.0 and ive suddenly got ~900 flow errors stemming from using static propTypes

I was late in replying to this, but you shouldn't have to manually fix this. The blog post for flow v0.53 mentions that you can use the flow-upgrade module to automatically convert your code to the latest version of Flow.

Installation

npm install -g flow-upgrade

Usage:

flow-upgrade # Upgrade all files that have a // @flow annotation

or

flow-upgrade --all # Upgrade all files, even if they don't have a // @flow annotation

Using propTypes is not the source of the errors by themselves, you're free to have both flow annotations and propTypes at the same time, however, flow errors if you don't annotate the props of your component.

@saadq shows you how to keep your existing behaviour (i.e., avoid errors), but if you want, you can also use codemods to automatically generates the flow types from your propTypes.

What is the reason for not just assuming Component<any> if no arguments passed in?

EDIT: See https://medium.com/flow-type/even-better-support-for-react-in-flow-25b0a3485627

Yeah, it really should have a default... TypeScript sets props to an empty object by default: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts#L280

So if your component doesn't take any props, you don't need to use a generic when doing

class MyComponent extends React.Component {
  ...
}

Any is avoided wherever possible; it essentially just turns off the type checker and it easily propagates. Anything you get from an any is any for example;

declare function f(): any;
var y = f() // y is any
var z = y.x // z is any

Instead, * is assumed, which I'm no expert on but afaik can essentially be thought of as "do your best to try to infer the type here".

Component<*> doesn't look as nice.

If you think of the <*> as a mini eye of Sauron it still doesn't look nice, but it looks a little cooler ¯\_(ツ)_/¯

It actually seems like the * type was deprecated in a recent commit :/

https://github.com/facebook/flow/commit/39968bcd1f5badccfd4303b2245a88203fa49377

well rip.

Explicitly type your props, kids.

Is there a way to deal with this if you're using comment types? Like, inline type annotations.

Was this page helpful?
0 / 5 - 0 ratings