Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component` [1] with less than 1 type argument #5869

Closed
codeuniquely opened this issue Feb 25, 2018 · 14 comments
Closed

Component` [1] with less than 1 type argument #5869

codeuniquely opened this issue Feb 25, 2018 · 14 comments

Comments

@codeuniquely
Copy link

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;
@saadq
Copy link

saadq commented Feb 25, 2018

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.

@codeuniquely
Copy link
Author

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
]),

@idiostruct
Copy link

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

myProp: React.ChildrenArray<React.Node>

@haxxxton
Copy link

haxxxton commented Apr 3, 2018

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

@saadq
Copy link

saadq commented Apr 3, 2018

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

@AugustinLF
Copy link
Contributor

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.

@vjpr
Copy link

vjpr commented May 7, 2018

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

@saadq
Copy link

saadq commented May 7, 2018

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 {
  ...
}

@mrkev
Copy link
Contributor

mrkev commented May 7, 2018

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".

@vjpr
Copy link

vjpr commented May 7, 2018

Component<*> doesn't look as nice.

@mrkev
Copy link
Contributor

mrkev commented May 7, 2018

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

@saadq
Copy link

saadq commented May 7, 2018

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

39968bc

@mrkev
Copy link
Contributor

mrkev commented May 7, 2018

well rip.

Explicitly type your props, kids.

@olleharstedt
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants