Skip to content

Commit 1ee4fbc

Browse files
committed
refactor: rename 'ExactValidator' validator to 'NoExtraPropsValidator'
The name was not correct, since the validator does just check that no extra props are passed. The 'prop-tpyes' 'PropTypes.exact' validator cannot be used on the root object assigned to a component, so it is of no use to us in this case. Closes #49.
1 parent 04605b8 commit 1ee4fbc

File tree

3 files changed

+42
-19
lines changed

3 files changed

+42
-19
lines changed

src/__tests__/types/propTypes.js

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import test from 'ava' // eslint-disable-line import/no-extraneous-dependencies
55

66
import MakeConsoleHook, { ConsoleOutput } from '../internals/ConsoleHook'
77
import FlagIconFactory from '../../'
8-
import { AddExactValidator } from '../../functions/propTypes'
8+
import { AddNoExtraPropsValidator } from '../../functions/propTypes'
99

1010
/**
1111
* TODO: remove 'ConsoleHook' as soon as possible. SEE: "Add ability to throw
@@ -67,19 +67,36 @@ test('FlagIconOptionsType', (t: *) => {
6767
consoleHook.detach()
6868
})
6969

70-
test('exact validator', (t: *) => {
70+
test('No extra props validator', (t: *) => {
7171
const consoleHook = MakeConsoleHook({ outputType: ConsoleOutput.error })
72-
const propsTypes = AddExactValidator({
72+
const propsTypes = AddNoExtraPropsValidator({
7373
code: PropTypes.string.isRequired,
7474
})
7575

7676
PropTypes.checkPropTypes(
7777
propsTypes,
7878
{ code: 'it', additional: 'lorem' },
7979
'key',
80-
'Exact validator test',
80+
'No extra props validator test',
8181
)
82+
8283
t.truthy(consoleHook.flushLog())
8384

84-
consoleHook.detach()
85+
// `AddNoExtraPropsValidator` is not an `exact` validator and doesn't check if
86+
// a prop was not passed. It triggers an error if it finds undeclared, extra props.
87+
// This means the user has to set`.isRequired` to check that a prop is required.
88+
const propsTypesTwo = AddNoExtraPropsValidator({
89+
lorem: PropTypes.string,
90+
ipsum: PropTypes.bool,
91+
})
92+
93+
PropTypes.checkPropTypes(
94+
propsTypesTwo,
95+
{},
96+
'key',
97+
'No extra props validator test',
98+
)
99+
100+
// No errors because there are no `extra` props.
101+
t.falsy(consoleHook.flushLog())
85102
})

src/functions/propTypes.js

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export const AddThemeStylesValidator = (
6666
*
6767
* SEE: https://github.com/reactjs/prop-types
6868
*/
69-
const fnExactValidator = (
69+
const fnNoExtraPropsValidator = (
7070
// prop-types Object supplied by the user. i.e {lorem: PropTypes.string}
7171
propsObject: PropsTypeObjectType,
7272
// prop-values Object supplied by the user. i.e {lorem: 'ipsum'}
@@ -90,29 +90,34 @@ const fnExactValidator = (
9090

9191
/**
9292
* Adds a 'custom validator' function to `obj`; this function makes sure that any
93-
* 'prop' passed by the user at runtime exists in `obj`, otherwise it throws an Error.
94-
* `obj` is a 'props' object, the one you would assign to `SomeComponent.propTypes`
93+
* 'prop' passed by the user at runtime exists as a key in `obj`, otherwise it throws
94+
* an Error. `obj` is a 'props' object, the one you would assign to `SomeComponent.propTypes`
9595
* or pass to `PropTypes.checkPropTypes()`. i.e {lorem: PropTypes.string}
9696
*
97-
* We use bind() to make a new `fnExactValidator` function with the first argument
97+
* We use bind() to make a new `fnNoExtraPropsValidator` function with the first argument
9898
* set as: `obj`. We need to do this because `prop-types` doesn't pass this object
99-
* to 'custom validator' functions such as `fnExactValidator`.
99+
* to 'custom validator' functions such as `fnNoExtraPropsValidator`.
100+
*
101+
* This type of validation is NOT the runtime equivalent to Flow's 'exact object
102+
* types', since we don't check if any required `prop-types` props have been supplied
103+
* or not, relying on the user to have specified an appropriate `isRequired` prop-type
104+
* for those.
100105
*
101-
* This type of validation is the runtime equivalent to Flow's 'exact object types'.
102106
* SEE: https://flow.org/en/docs/types/objects/#toc-exact-object-types
103107
*/
104108
// eslint-disable-next-line import/prefer-default-export, max-len
105-
export const AddExactValidator = (
109+
export const AddNoExtraPropsValidator = (
106110
obj: PropsTypeObjectType,
107111
): PropsTypeObjectType => {
108-
const validatorKeyName = '__exact__'
112+
const validatorKeyName = '__no__extra__props__validator___'
109113
if (Object.prototype.hasOwnProperty.call(obj, validatorKeyName)) {
110-
// TODO: print a message or throw when not in production?
111-
return obj // The custom validator is already 'installed'.
114+
// The custom validator is already 'installed', or the user has managed to
115+
// somehow use `validatorKeyName`.
116+
return obj
112117
}
113118

114119
return {
115120
...obj,
116-
[validatorKeyName]: fnExactValidator.bind(this, obj),
121+
[validatorKeyName]: fnNoExtraPropsValidator.bind(this, obj),
117122
}
118123
}

src/types/propTypes.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import PropTypes from 'prop-types'
33
import { getRotates, getFlips, getSizes } from '../functions/props'
44
import {
5-
AddExactValidator,
5+
AddNoExtraPropsValidator,
66
AddThemeStylesValidator,
77
} from '../functions/propTypes'
88
import type { FlagIconCodeType, PropsTypeObjectType } from '../types/flow'
@@ -49,7 +49,8 @@ const makeFlagIconPropsTypeObject = <T>(
4949
export const MakeFlagIconPropsType = <T>(
5050
codes: MaybeFlagIconCodeType<T>[],
5151
// eslint-disable-next-line arrow-body-style
52-
): PropsTypeObjectType => AddExactValidator(makeFlagIconPropsTypeObject(codes))
52+
): PropsTypeObjectType =>
53+
AddNoExtraPropsValidator(makeFlagIconPropsTypeObject(codes))
5354

5455
const flagIconOptionsType = {
5556
customCodes: PropTypes.object,
@@ -58,4 +59,4 @@ const flagIconOptionsType = {
5859
}
5960

6061
export const MakeFlagIconOptionsPropType = (): PropsTypeObjectType =>
61-
AddExactValidator(AddThemeStylesValidator(flagIconOptionsType))
62+
AddNoExtraPropsValidator(AddThemeStylesValidator(flagIconOptionsType))

0 commit comments

Comments
 (0)