diff --git a/packages/material-ui-utils/src/requirePropFactory.d.ts b/packages/material-ui-utils/src/requirePropFactory.d.ts index 63ae30db9f2831..b4759fe6393271 100644 --- a/packages/material-ui-utils/src/requirePropFactory.d.ts +++ b/packages/material-ui-utils/src/requirePropFactory.d.ts @@ -1 +1,3 @@ -export default function requirePropFactory(componentNameInError: string): any; +import * as React from 'react'; + +export default function requirePropFactory(componentNameInError: string, Component?: React.ComponentType): any; diff --git a/packages/material-ui-utils/src/requirePropFactory.js b/packages/material-ui-utils/src/requirePropFactory.js index e8e8b24a2a7259..dd91a063463f8d 100644 --- a/packages/material-ui-utils/src/requirePropFactory.js +++ b/packages/material-ui-utils/src/requirePropFactory.js @@ -1,4 +1,4 @@ -export default function requirePropFactory(componentNameInError) { +export default function requirePropFactory(componentNameInError, Component) { if (process.env.NODE_ENV === 'production') { return () => null; } @@ -12,6 +12,13 @@ export default function requirePropFactory(componentNameInError) { ) => { const propFullNameSafe = propFullName || propName; + const defaultTypeChecker = Component?.propTypes?.[propFullNameSafe]; + let defaultTypeCheckerResult = null; + + if(defaultTypeChecker) { + defaultTypeCheckerResult = defaultTypeChecker(props, propName, componentName, location, propFullName) + } + if (typeof props[propName] !== 'undefined' && !props[requiredProp]) { return new Error( `The prop \`${propFullNameSafe}\` of ` + @@ -19,7 +26,7 @@ export default function requirePropFactory(componentNameInError) { ); } - return null; + return defaultTypeCheckerResult; }; return requireProp; } diff --git a/packages/material-ui-utils/src/requirePropFactory.test.js b/packages/material-ui-utils/src/requirePropFactory.test.js index f527d088a4e19d..bb5ce3d79dd845 100644 --- a/packages/material-ui-utils/src/requirePropFactory.test.js +++ b/packages/material-ui-utils/src/requirePropFactory.test.js @@ -1,4 +1,5 @@ import { expect } from 'chai'; +import { spy } from 'sinon'; import requirePropFactory from './requirePropFactory'; describe('requirePropFactory', () => { @@ -83,6 +84,28 @@ describe('requirePropFactory', () => { }); }); }); + + it('should chain the proptypes with the default prop types coming from the component', () => { + const Test = () => null; + const mock = spy(); + Test.propTypes = { + test: mock, + }; + + const props = {}; + const propName = 'test'; + props[propName] = true; + + const requireProp = requirePropFactory('Test', Test); + + const result = requireProp('otherProp'); + result(props, propName, undefined, undefined, undefined); + + expect(mock.callCount).to.equal(1); + expect(mock.args[0]).to.deep.equal( + [props, propName, undefined, undefined, undefined], + ); + }); }); }); }); diff --git a/packages/material-ui/src/Grid/Grid.js b/packages/material-ui/src/Grid/Grid.js index ce5c22aa23a4b5..c23b2b0bbbc1f4 100644 --- a/packages/material-ui/src/Grid/Grid.js +++ b/packages/material-ui/src/Grid/Grid.js @@ -424,7 +424,7 @@ Grid.propTypes = { }; if (process.env.NODE_ENV !== 'production') { - const requireProp = requirePropFactory('Grid'); + const requireProp = requirePropFactory('Grid', Grid); // eslint-disable-next-line no-useless-concat Grid['propTypes' + ''] = { // eslint-disable-next-line react/forbid-foreign-prop-types