mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Merge pull request #6377 from puradox/proptypes-symbol
Add new primitive PropType `Symbol`
(cherry picked from commit 7bf96c08e6)
This commit is contained in:
committed by
Paul O’Shannessy
parent
2ef148d1ee
commit
f112083c7a
@@ -33,6 +33,7 @@
|
||||
"browserify": "^13.0.0",
|
||||
"bundle-collapser": "^1.1.1",
|
||||
"coffee-script": "^1.8.0",
|
||||
"core-js": "^2.2.1",
|
||||
"coveralls": "^2.11.6",
|
||||
"del": "^2.0.2",
|
||||
"derequire": "^2.0.3",
|
||||
|
||||
@@ -73,6 +73,7 @@ var ReactPropTypes = {
|
||||
number: createPrimitiveTypeChecker('number'),
|
||||
object: createPrimitiveTypeChecker('object'),
|
||||
string: createPrimitiveTypeChecker('string'),
|
||||
symbol: createPrimitiveTypeChecker('symbol'),
|
||||
|
||||
any: createAnyTypeChecker(),
|
||||
arrayOf: createArrayOfTypeChecker,
|
||||
@@ -406,6 +407,25 @@ function isNode(propValue) {
|
||||
}
|
||||
}
|
||||
|
||||
function isSymbol(propType, propValue) {
|
||||
// Native Symbol.
|
||||
if (propType === 'symbol') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol'
|
||||
if (propValue['@@toStringTag'] === 'Symbol') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fallback for non-spec compliant Symbols which are polyfilled.
|
||||
if (typeof Symbol === 'function' && propValue instanceof Symbol) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Equivalent of `typeof` but with special handling for array and regexp.
|
||||
function getPropType(propValue) {
|
||||
var propType = typeof propValue;
|
||||
@@ -418,6 +438,9 @@ function getPropType(propValue) {
|
||||
// passes PropTypes.object.
|
||||
return 'object';
|
||||
}
|
||||
if (isSymbol(propType, propValue)) {
|
||||
return 'symbol';
|
||||
}
|
||||
return propType;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,12 @@ describe('ReactPropTypes', function() {
|
||||
'Invalid prop `testProp` of type `object` supplied to ' +
|
||||
'`testComponent`, expected `string`.'
|
||||
);
|
||||
typeCheckFail(
|
||||
PropTypes.string,
|
||||
Symbol(),
|
||||
'Invalid prop `testProp` of type `symbol` supplied to ' +
|
||||
'`testComponent`, expected `string`.'
|
||||
);
|
||||
});
|
||||
|
||||
it('should fail date and regexp correctly', function() {
|
||||
@@ -106,6 +112,7 @@ describe('ReactPropTypes', function() {
|
||||
typeCheckPass(PropTypes.object, {});
|
||||
typeCheckPass(PropTypes.object, new Date());
|
||||
typeCheckPass(PropTypes.object, /please/);
|
||||
typeCheckPass(PropTypes.symbol, Symbol());
|
||||
});
|
||||
|
||||
it('should be implicitly optional and not warn without values', function() {
|
||||
@@ -124,6 +131,7 @@ describe('ReactPropTypes', function() {
|
||||
typeCheckPass(PropTypes.any, 0);
|
||||
typeCheckPass(PropTypes.any, 'str');
|
||||
typeCheckPass(PropTypes.any, []);
|
||||
typeCheckPass(PropTypes.any, Symbol());
|
||||
});
|
||||
|
||||
it('should be implicitly optional and not warn without values', function() {
|
||||
@@ -150,6 +158,7 @@ describe('ReactPropTypes', function() {
|
||||
typeCheckPass(PropTypes.arrayOf(PropTypes.number), [1, 2, 3]);
|
||||
typeCheckPass(PropTypes.arrayOf(PropTypes.string), ['a', 'b', 'c']);
|
||||
typeCheckPass(PropTypes.arrayOf(PropTypes.oneOf(['a', 'b'])), ['a', 'b']);
|
||||
typeCheckPass(PropTypes.arrayOf(PropTypes.symbol), [Symbol(), Symbol()]);
|
||||
});
|
||||
|
||||
it('should support arrayOf with complex types', function() {
|
||||
@@ -490,6 +499,10 @@ describe('ReactPropTypes', function() {
|
||||
PropTypes.objectOf(PropTypes.oneOf(['a', 'b'])),
|
||||
{a: 'a', b: 'b'}
|
||||
);
|
||||
typeCheckPass(
|
||||
PropTypes.objectOf(PropTypes.symbol),
|
||||
{a: Symbol(), b: Symbol(), c: Symbol()}
|
||||
);
|
||||
});
|
||||
|
||||
it('should support objectOf with complex types', function() {
|
||||
@@ -545,6 +558,12 @@ describe('ReactPropTypes', function() {
|
||||
'Invalid prop `testProp` of type `string` supplied to ' +
|
||||
'`testComponent`, expected an object.'
|
||||
);
|
||||
typeCheckFail(
|
||||
PropTypes.objectOf(PropTypes.symbol),
|
||||
Symbol(),
|
||||
'Invalid prop `testProp` of type `symbol` supplied to ' +
|
||||
'`testComponent`, expected an object.'
|
||||
);
|
||||
});
|
||||
|
||||
it('should not warn when passing an empty object', function() {
|
||||
@@ -782,6 +801,36 @@ describe('ReactPropTypes', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Symbol Type', function() {
|
||||
it('should warn for non-symbol', function() {
|
||||
typeCheckFail(
|
||||
PropTypes.symbol,
|
||||
'hello',
|
||||
'Invalid prop `testProp` of type `string` supplied to ' +
|
||||
'`testComponent`, expected `symbol`.'
|
||||
);
|
||||
typeCheckFail(
|
||||
PropTypes.symbol,
|
||||
function() { },
|
||||
'Invalid prop `testProp` of type `function` supplied to ' +
|
||||
'`testComponent`, expected `symbol`.'
|
||||
);
|
||||
typeCheckFail(
|
||||
PropTypes.symbol,
|
||||
{
|
||||
'@@toStringTag': 'Katana',
|
||||
},
|
||||
'Invalid prop `testProp` of type `object` supplied to ' +
|
||||
'`testComponent`, expected `symbol`.'
|
||||
);
|
||||
});
|
||||
|
||||
it('should not warn for a polyfilled Symbol', function() {
|
||||
var CoreSymbol = require('core-js/library/es6/symbol');
|
||||
typeCheckPass(PropTypes.symbol, CoreSymbol('core-js'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('Custom validator', function() {
|
||||
beforeEach(function() {
|
||||
jest.resetModuleRegistry();
|
||||
|
||||
Reference in New Issue
Block a user