Skip to content
This repository has been archived by the owner on Sep 1, 2024. It is now read-only.

Feature request: warn when property not in propTypes is passed into component #11

Closed
aweary opened this issue Apr 9, 2017 · 10 comments
Closed

Comments

@aweary
Copy link
Contributor

aweary commented Apr 9, 2017

Original issue: facebook/react#1587

@hakunin
Copy link

hakunin commented Apr 10, 2017

The best workaround right now is to use https://github.com/airbnb/prop-types

@crowdwave
Copy link

This meets my basic need which is just to know if the provided prop names don't match the expected prop names as defined in proptypes.

  componentDidMount() {
    let matchPropTypes = Object.keys(this.constructor.propTypes).every((a, index) => a === Object.keys(this.props)[index])
    if (!matchPropTypes) {console.log('propTypes do not match props', Object.keys(this.constructor.propTypes), Object.keys(this.props))}
  }

@Aprillion
Copy link

remix-run/react-router#5114 is an example why this warning would by highly useful - ideally if the library authors could force it in their propTypes...

@AndersDJohnson
Copy link

Adding to @hakunin's answer in #11 (comment), I think we'd use forbidExtraProps from https://github.com/airbnb/prop-types.

@mfru
Copy link

mfru commented Feb 15, 2018

Is using AirBnB's proptypes still the recommended solution?

@coconup
Copy link

coconup commented Jun 27, 2018

Here's an easy, DYI solution partially inspired by Airbnb's:

utils/propTypesHelpers.js

import PropTypes from 'prop-types';

export function conditionalPropType(condition, message, fullMessageOverride = false) {
  if(typeof condition !== 'function') throw new TypeError(`Wrong argument type 'condition' supplied to 'conditionalPropType'. Expected 'function', got '${typeof(condition)}'.`);

  return function(props, propName, componentName) {
    const conditionResult = condition(props, propName, componentName);
    if (conditionResult) {
      const parsedMessage = typeof(message) === 'function' ? message(conditionResult, props, propName, componentName) : message;
      const defaultMessage = `Invalid prop '${propName}' '${props[propName]}' supplied to '${componentName}'. ${parsedMessage}`;
      return new Error(fullMessageOverride ? parsedMessage : defaultMessage);
    }
  }
}

export function forbidExtraProps(propTypes) {
  if (typeof propTypes !== 'object') {
    throw new TypeError(`Wrong argument type 'propTypes' supplied to 'forbidExtraProps'. Expected 'object', got '${typeof(propTypes)}'.`);
  }

  const allowedPropKeys = Object.keys(propTypes);

  return {
    ...propTypes,
    _extraPropsCheck: conditionalPropType(
      props => {
        const unknownProps = Object.keys(props).filter(p => !allowedPropKeys.includes(p));
        return unknownProps.length > 0 ? unknownProps : false;
      }, 
      (unknownProps, _p, _pN, componentName) => `Unknown props found in component '${componentName}': ${unknownProps.join(', ')}.`,
      true,
    )
  }
}

app/components/MyComponent.js

import { forbidExtraProps } from 'utils/propTypesHelpers';

[...]

MyComponent.propTypes = forbidExtraProps({
   ...
})

It'll give you a conditionalPropType helper as a bonus too.

@garfieldnate
Copy link

It took me a while to figure out that Button has no style attribute. I had assumed that it would die if I had passed in an unknown attribute, and I was puzzled by my styles not being applied to buttons.

@ljharb
Copy link
Contributor

ljharb commented Feb 21, 2019

This seems done with #87 and exact.

@ljharb ljharb closed this as completed Feb 21, 2019
@williamrjribeiro
Copy link

Apparently this feature is not yet implemented yet. See #263

@ZacharyRSmith
Copy link

ZacharyRSmith commented Jul 11, 2020

If you don't want to change to airbnb's prop-types, this module may be helpful: https://www.npmjs.com/package/prop-types-exact

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

No branches or pull requests