Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new primitive PropType Symbol #6377

Merged
merged 14 commits into from
May 10, 2016
Merged

Add new primitive PropType Symbol #6377

merged 14 commits into from
May 10, 2016

Conversation

puradox
Copy link
Contributor

@puradox puradox commented Mar 30, 2016

With the edition of ECMA-262, we now have a new primative type called Symbol. This primitive type should be added to the PropTypes, as users will eventually be using Symbols in their props for describing unique and immutable data, such as identifiers.

With the edition of ECMA-262, we now have a new primative type called
Symbol. This primative type should be added to the PropTypes, as users
will eventually be using Symbols in their props for describing unique
and immutable data, such as identifiers.
I believe that I covered all the typical use cases for Symbols.
If you think that I missed one, feel free to contribute.
@puradox
Copy link
Contributor Author

puradox commented Mar 30, 2016

This relates to issue #4917

@gaearon
Copy link
Collaborator

gaearon commented Mar 30, 2016

If the user is using a Babel polyfill, would a component defined with PropTypes.symbol print a warning?
How do we want to handle this scenario?

@aweary
Copy link
Contributor

aweary commented Mar 30, 2016

@gaearon I'd imagine that getPropType would return 'function' for a polyfill'd Symbol right? If so the warning could note that a PropTypes.symbol was found to be a function and warn that it could be either 1) an invalid prop or 2) due to a pollyfill.

@borisyankov
Copy link
Contributor

I don't think showing a warning to users of polyfill is desirable.
Maybe, the code can 'interrogate' the function somehow and determine if it is a polyfill for Symbol?

@puradox
Copy link
Contributor Author

puradox commented Mar 30, 2016

@gaearon You bring up an interesting point. There could be a check if global._babelPolyfill == true (source) and then handle the polyfill of Symbol accordingly. From there, one possible solution is using instanceof instead of typeof.

@brigand
Copy link
Contributor

brigand commented Mar 31, 2016

We could do what babel compiles typeof x === 'symbol' to:

'use strict';

// refactored for readability
var nativeSymbolSupported = typeof Symbol === "function" && typeof Symbol.iterator === "symbol";
var _typeof = nativeSymbolSupported
 ? function (obj) { return typeof obj; }
 : function (obj) {
    if (obj && typeof Symbol === "function" && obj.constructor === Symbol) {
      return "symbol"
    }
    else {
      typeof obj; 
    }
  };

(typeof x === 'undefined' ? 'undefined' : _typeof(x)) === 'symbol';

@gaearon gaearon mentioned this pull request Mar 31, 2016
@puradox
Copy link
Contributor Author

puradox commented Mar 31, 2016

@brigand I like that approach much better 👍

We could further simplify and extend this to getPropType() to return symbol make sure that functions aren't being mistaken for Symbols

// Equivalent of `typeof` but with special handling for array and regexp.
function getPropType(propValue) {
  var propType = typeof propValue;
  // ...
  if (propType === 'function' && propValue instanceof Symbol) {
    return 'symbol';
  }
  return propType;
}

@RaitoBezarius
Copy link
Contributor

@puradox That's definitely a good idea! But how can you be sure that Symbol is available in the namespace? And if it is an instance of it? On my pull request, we can use sort of duck typing approach and say, if it behaves like a Symbol: all symbols have a toStringTag property which is equal to the default name (toString name) which is always: symbol.

What do you think so?

@puradox
Copy link
Contributor Author

puradox commented Mar 31, 2016

@RaitoBezarius You bring up a good point with Symbol being undefined in the global namespace. We can easily check for that using typeof Symbol

So the check in getPropType() would actually be

if (propType === 'function' && typeof Symbol === 'function' && propValue instanceof Symbol) {
  return 'symbol';
}

Does this address your concern?

@RaitoBezarius
Copy link
Contributor

Awesome, according to core-js polyfill: https://github.com/zloirock/core-js/blob/master/modules/es6.symbol.js#L68 -- the test works well. (because core-js is always in the global namespace, I think?)


For this polyfill: https://github.com/medikoo/es6-symbol

https://github.com/medikoo/es6-symbol/blob/master/is-symbol.js

It sounds like that it's not that spec-compliant because it should be toStringTag and not @@toStringTag, but we could definitely check for this too.


For this polyfill: https://github.com/component/symbol
We won't detect it, seems like. It does not respect the spec, all we can know is: look for a __key__ property whose prototype property (Object.prototype.key) is equal to undefined (the getter returns nothing), but we can modify it using the setter and look for the toString method for changes. (The code is clearer than my text).


It should solve the problem of testing when no Symbol is available in the global namespace for a strange reason (polyfill is "sandboxed" or not leaked, etc...)

Would you like me to write some parts of the code and let you cherry-pick them on your branch so that we can complete this PR ?

@puradox
Copy link
Contributor Author

puradox commented Mar 31, 2016

@RaitoBezarius Yeah, it would be great if you could write some parts.

Most ES6 polyfills will add support by implementing `Symbol` as a
function. This causes `typeof` to return `function` rather than `symbol`
for polyfilled clients.
@facebook-github-bot
Copy link

@puradox updated the pull request.

1) If it is a native Symbol
2) If it is spec-compliant
3) Try to match non-spec compliant polyfill by a instanceof check on Symbol if it exists in the global namespace
Improve symbol check for (local) polyfills
@RaitoBezarius
Copy link
Contributor

@gaearon What are you feelings on adding Symbols polyfills as devDependencies for the tests? Do you think it's a acceptable idea?

@puradox Will push some fix for the lint issues (my bad, some habits sticks when switching between projects :D), as for the test which fails, I'll merge back the current master of React inside my fork and try with this, will open two PR (one for the lint, one for the unit test fix).

Please, if you have some time, review the code so we can move forward and get this merged 🎉 !
Thanks a lot!

@gaearon
Copy link
Collaborator

gaearon commented Apr 6, 2016

We will review this after 15.0 is out. Feel free to ping me if we forget to (but we shouldn't).

@puradox
Copy link
Contributor Author

puradox commented Apr 7, 2016

Can we get someone with write access to rerun the Travis-CI tests?

Cloning into 'facebook/react'...
remote: GitHub is offline for maintenance. See http://status.github.com for more info.
fatal: unable to access 'https://github.com/facebook/react.git/': The requested URL returned error: 503

@jimfb
Copy link
Contributor

jimfb commented Apr 7, 2016

Rerunning now

There seems to be a bug with medikoo/es6-symbol where the global state
affects the implementation of the polyfill. I found this by running the
individual test file alone then running all the tests using `grunt
test`. I found that it passes when ran alone and failed when ran
collectively.

I did not find this buggy behavior with zloirock/core-js's
implementation of a polyfill for Symbol. Thus, removing I will keep the
more popular polyfill (core-js) and remove the buggy polyfill
(es6-symbol).

If you are reading this and can think of a confounding factor that is
causing this bug, please let me know and we can try to work together to
add support for medikoo/es6-symbol.
@facebook-github-bot
Copy link

@puradox updated the pull request.

"coveralls": "^2.11.6",
"del": "^2.0.2",
"derequire": "^2.0.3",
"es6-symbol": "^3.0.2",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? Doesn’t appear to be used.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a leftover from a @puradox fix on tests — I will clean up this!

On Sat, Apr 9, 2016, 00:26 Dan Abramov [email protected] wrote:

In package.json
#6377 (comment):

 "coveralls": "^2.11.6",
 "del": "^2.0.2",
 "derequire": "^2.0.3",
  • "es6-symbol": "^3.0.2",

Is this necessary? Doesn’t appear to be used.


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
https://github.com/facebook/react/pull/6377/files/ad94295f139a8190286852e14a5c731065f5f0ba#r59097655

Ryan Lahfa, de mon téléphone.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @RaitoBezarius! I forgot to remove this dependency when removing unit test support for es6-symbol.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have pushed a fix on your fork to remove the dependency, so that we can
unblock the code review.

Kind regards, Ryan Lahfa

@facebook-github-bot
Copy link

@puradox updated the pull request.

@gaearon gaearon added this to the 15.x milestone Apr 14, 2016
@gaearon gaearon merged commit 7bf96c0 into facebook:master May 10, 2016
@gaearon
Copy link
Collaborator

gaearon commented May 10, 2016

Merging since this was accepted.

@zpao zpao modified the milestones: 15.y.0, 15-next Jun 1, 2016
zpao pushed a commit to zpao/react that referenced this pull request Jun 8, 2016
Add new primitive PropType `Symbol`
(cherry picked from commit 7bf96c0)
zpao pushed a commit that referenced this pull request Jun 14, 2016
Add new primitive PropType `Symbol`
(cherry picked from commit 7bf96c0)
@zpao zpao modified the milestones: 15-next, 15.2.0 Jun 14, 2016
ZauberNerd added a commit to ZauberNerd/react-docgen that referenced this pull request Sep 5, 2016
React has introduced a new primitive PropType "symbol".
facebook/react#6377
This change adds support for that propType so that it is not reported
as "custom".
fkling pushed a commit to reactjs/react-docgen that referenced this pull request Sep 27, 2016
React has introduced a new primitive PropType "symbol".
facebook/react#6377
This change adds support for that propType so that it is not reported
as "custom".
toptaldev92 pushed a commit to toptaldev92/react-docgen that referenced this pull request Jul 28, 2021
React has introduced a new primitive PropType "symbol".
facebook/react#6377
This change adds support for that propType so that it is not reported
as "custom".
bright0824 added a commit to bright0824/react-docgen that referenced this pull request Jul 14, 2023
React has introduced a new primitive PropType "symbol".
facebook/react#6377
This change adds support for that propType so that it is not reported
as "custom".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants