diff --git a/README.md b/README.md index 0a941d3..cd00805 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,10 @@ yarn add @dhis2/prop-types

Ensure the prop value is an array with a length between a minimum and maximum. If a third propType argument is passed each item in the array needs to be of that prop-type

+
whitelistProps(propTypes)Object
+

Ensure that no other props, apart from the ones in the prop-types definition +have been passed tot the component

+
instanceOfComponent(Component)Error | null

Ensure the prop value is an instance of a certain component

@@ -54,6 +58,36 @@ LotsOfLists.propTypes = { mandatoryArrayBetweenOneAndTen: arrayWithLength(1,10).isRequired, } ``` + + +## whitelistProps(propTypes) ⇒ Object +Ensure that no other props, apart from the ones in the prop-types definition +have been passed tot the component + +**Kind**: global function +**Returns**: Object - Returns a copy of the original prop-types object with an appended +property `whitelistProps`, which is a prop-types validator that will return an error +if props have been added that the component that were not in the prop-types object + +| Param | Type | Description | +| --- | --- | --- | +| propTypes | object | The prop-types definition of the component | + +**Example** +```js +import React from 'react' +import propTypes from '@dhis2/prop-types' + +const MyComponent = ({ score, maxScore }) =>
{score} out of {maxScore}
+MyComponent.propTypes = propTypes.whitelistProps({ + score: propTypes.number, + maxScore: propTypes.number, +}) + +Note: `whitelistProps` is different from the `exact` method form the standard +prop-types library, because `whitelistProps` is meant to be applied on a full component +prop-type definition, while `exact` is meant to be a applied on an individual prop-type +``` ## instanceOfComponent(Component) ⇒ Error \| null diff --git a/src/forbidUnknownProps.js b/src/forbidUnknownProps.js new file mode 100644 index 0000000..5ae3a1f --- /dev/null +++ b/src/forbidUnknownProps.js @@ -0,0 +1,37 @@ +/** + * Ensure that no other props, apart from the ones in the prop-types definition + * have been passed tot the component + * @param {object} propTypes - The prop-types definition of the component + * @return {Object} Returns a copy of the original prop-types object with an appended + * property `whitelistProps`, which is a prop-types validator that will return an error + * if props have been added that the component that were not in the prop-types object + * @example + * import React from 'react' + * import propTypes from '@dhis2/prop-types' + * + * const MyComponent = ({ score, maxScore }) =>
{score} out of {maxScore}
+ * MyComponent.propTypes = propTypes.whitelistProps({ + * score: propTypes.number, + * maxScore: propTypes.number, + * }) + * + * Note: `whitelistProps` is different from the `exact` method form the standard + * prop-types library, because `whitelistProps` is meant to be applied on a full component + * prop-type definition, while `exact` is meant to be a applied on an individual prop-type + */ + +const whitelistProps = propTypes => ({ + ...propTypes, + whitelistProps: (props, _, componentName) => { + const unknownProps = Object.keys(props).filter( + propKey => !propTypes[propKey] + ) + if (unknownProps.length > 0) { + const list = unknownProps.join(', ') + return new Error(`${componentName}: unknown props found: ${list}`) + } + return null + }, +}) + +export { whitelistProps } diff --git a/src/index.js b/src/index.js index fbc7ea4..2df3725 100644 --- a/src/index.js +++ b/src/index.js @@ -1,16 +1,23 @@ import propTypes from 'prop-types' import { arrayWithLength } from './arrayWithLength.js' +import { whitelistProps } from './whitelistProps.js' import { instanceOfComponent } from './instanceOfComponent.js' import { mutuallyExclusive } from './mutuallyExclusive.js' const customPropTypes = { arrayWithLength, + whitelistProps, instanceOfComponent, mutuallyExclusive, } -export { arrayWithLength, instanceOfComponent, mutuallyExclusive } +export { + arrayWithLength, + whitelistProps, + instanceOfComponent, + mutuallyExclusive, +} export default { ...propTypes,