diff --git a/src/shared/utils/__tests__/traverseAllChildren-test.js b/src/shared/utils/__tests__/traverseAllChildren-test.js
index a4c8954db5..d981bb93f0 100644
--- a/src/shared/utils/__tests__/traverseAllChildren-test.js
+++ b/src/shared/utils/__tests__/traverseAllChildren-test.js
@@ -476,6 +476,39 @@ describe('traverseAllChildren', function() {
}
});
+ it('should allow extension of native prototypes', function() {
+ /*eslint-disable no-extend-native */
+ String.prototype.key = 'react';
+ Number.prototype.key = 'rocks';
+ /*eslint-enable no-extend-native */
+
+ var instance = (
+
+ {'a'}
+ {13}
+
+ );
+
+ var traverseFn = jasmine.createSpy();
+
+ traverseAllChildren(instance.props.children, traverseFn, null);
+ expect(traverseFn.calls.length).toBe(2);
+
+ expect(traverseFn).toHaveBeenCalledWith(
+ null,
+ 'a',
+ '.0'
+ );
+ expect(traverseFn).toHaveBeenCalledWith(
+ null,
+ 13,
+ '.1'
+ );
+
+ delete String.prototype.key;
+ delete Number.prototype.key;
+ });
+
it('should throw on object', function() {
expect(function() {
traverseAllChildren({a: 1, b: 2}, function() {}, null);
diff --git a/src/shared/utils/traverseAllChildren.js b/src/shared/utils/traverseAllChildren.js
index f7f7e878eb..62146c7431 100644
--- a/src/shared/utils/traverseAllChildren.js
+++ b/src/shared/utils/traverseAllChildren.js
@@ -47,7 +47,9 @@ function userProvidedKeyEscaper(match) {
* @return {string}
*/
function getComponentKey(component, index) {
- if (component && component.key != null) {
+ // Do some typechecking here since we call this blindly. We want to ensure
+ // that we don't block potential future ES APIs.
+ if (component && typeof component === 'object' && component.key != null) {
// Explicit key
return wrapUserProvidedKey(component.key);
}