Eslint-plugin-react: react/prop-types breaks when propTypes use spread operator

Created on 12 Mar 2019  路  7Comments  路  Source: yannickcr/eslint-plugin-react

In a component similar to this one:

static propTypes = {
  foo: PropTypes.string,
}

componentDidMount() {
  const { foo, bar } = this.props;
  console.log(foo, bar);
}

react/prop-types complains that 'bar' is missing in props validation, which is correct.

However, if I change the propTypes to

static propTypes = {
  foo: PropTypes.string,
  ...{ other: PropTypes.bool, stuff: PropTypes.func },
}

eslint will pass, which seems to be a bug.

I did not find any similar issue here on github, but maybe I just missed it.

Most helpful comment

What you suggest is going against DRY quite a bit though and this is an extremely common React pattern so I don鈥檛 think people are going to stop doing it.

All 7 comments

The spread is basically impossible to statically analyze; but I鈥檇 still expect the error on foo, since it鈥檚 defined statically.

You mean bar, right?

I think the addition of _something_ (even if not statically analyzable) to the propTypes should not prevent the rest of the propTypes from being statically analyzable, because it seems like this is the case.

ahhh right, that's why. Because we can't determine if bar is present or not, we currently treat a spread as "all possible props".

If we errored on bar here, and you'd actually brought it in via the spread, then you'd be forced to silence the false positive, or to duplicate the bar declaration.

I see! That's what I presumed. Thank you for clarifying that!

I wonder if would make sense to make an option out of that:

  1. Ignore the spreaded objects, which could lead to false positives
  2. Treat the spread as "all possible prop" as it is right now.

I don't know if that's worth the effort, though.

I'm noticing something similar. I have the following rules set up

"react/prop-types": [
  "error",
  {
    "ignore": [],
    "customValidators": [],
    "skipUndeclared": false
  }
],

And the following component

const Force = ({ type, emitterId, id, fx, fy, fz, life, easing, update }) => (
  <Behaviour {...{ type, emitterId, id, easing, update }}>
    <ControlsBlock>
      <NumberInput
        defaultValue={fx}
        label="fx"
        onValueUpdate={fx => update(type, emitterId, id, { fx })}
      />
      <NumberInput
        defaultValue={fy}
        label="fy"
        onValueUpdate={fy => update(type, emitterId, id, { fy })}
      />
      <NumberInput
        defaultValue={fz}
        label="fz"
        onValueUpdate={fz => update(type, emitterId, id, { fz })}
      />
    </ControlsBlock>
  </Behaviour>
);

Does not cause any prop type validations to display errors. If I remove the spread object completely, the rules work again.

I鈥檇 suggest avoiding spreading props entirely; one big benefit is regaining the static analysis that doing so prevents.

What you suggest is going against DRY quite a bit though and this is an extremely common React pattern so I don鈥檛 think people are going to stop doing it.

Was this page helpful?
0 / 5 - 0 ratings