-
Notifications
You must be signed in to change notification settings - Fork 30.5k
[WIP] [React] Return type of React.SFC is wrong #23422
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
Conversation
|
@FredyC Thank you for submitting this PR! 🔔 @johnnyreilly @bbenezech @pzavolinsky @digiguru @ericanderson @morcerf @tkrotoff @DovydasNavickas @onigoetz @theruther4d @guilhermehubner @JoshuaKGoldberg @jrakotoharisoa - please review this PR in the next few days. Be sure to explicitly select If no reviewer appears after a week, a DefinitelyTyped maintainer will review the PR instead. |
|
@FredyC The Travis CI build failed! Please review the logs for more information. Once you've pushed the fixes, the build will automatically re-run. Thanks! |
| type SFC<P = {}> = StatelessComponent<P>; | ||
| interface StatelessComponent<P = {}> { | ||
| (props: P & { children?: ReactNode }, context?: any): ReactElement<any> | null; | ||
| (props: P & { children?: ReactNode }, context?: any): ReactNode; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is slightly wrong because it can't return undefined. ReactNode definition includes undefined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, in that case, it's wrong altogether, because ReactNode is also used as a return type of render method for a class component.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough.
|
Could you fix the issues with the CI build please? |
|
@johnnyreilly Well, as I said in OP...
I am kinda waiting for someone more capable of figuring this out :/ |
|
I took a quick look, given they all fail on typescript@next, you may be hitting an issue with typescript itself? |
|
here is the Typescript PR about that : microsoft/TypeScript#20239 |
|
@polco Ah, I've missed that issue, thanks. So I guess we have to wait for this. I am curious though, how is it possible that having |
|
Because the Typescript JSX parser has some custom React logic. |
|
Out of curiosity, if you change this line to |
Remove undefined from ReactNode
|
It look like the many breaks in travis are all packages who depend in @johnnyreilly @mhegazy we (likely) don't need to change TS to fix the original problem, (as microsoft/TypeScript#20239 made it look like we may have), but this is probably the biggest break I've ever seen in the react |
|
Ah, there is also an issue in TS. We couple the return type of the factory function with the allowable return types of a SFC or class |
|
So do we have any ideas how to solve this? I am still pretty much confused about some things here and I am not sure what should be the next step. Perhaps fix the mentioned problem in TS first? Should I create an issue for that? |
|
Yesterday I tried to change the types to make it possible to restrict children to certain components. (eg can only have s). The idea was to capture the type into JSX.Element so that children could be more restrictive. I also hit this problem in my efforts. I bring this up so that if we make a breaking change to TS, perhaps we could be sure to enable this as possible. |
|
@weswigham I am curious. Will this PR be still necessary after your work in microsoft/TypeScript#21699 is finished? It's rather overwhelming and I am not sure what to take from that. |
| const StatelessComponent4: React.SFC = props => null; | ||
|
|
||
| // allows string as return value | ||
| const StatelessComponent5: React.SFC = props => "string"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be useful to also include an $ExpectError for the undefined return.
|
@FredyC To keep things tidy, we have to close PRs that aren't mergeable but don't have activity from their author. No worries, though - please open a new PR if you'd like to continue with this change. Thank you! |
|
@gaearon @JoshuaKGoldberg @FredyC Currently this make const A: React.FunctionComponent<{}> = props => props.childrenI had to do the following const A: React.FunctionComponent<{}> = props => props.children as React.ReactElement<any>Any idea ? |
|
@weswigham Does it mean it will never be fixed beacuse it's a breaking change? Can we do anything about informing community to have this fixed? |
Please fill in this template.
npm run lint package-name(ortscif notslint.jsonis present).If changing an existing definition:
tslint.jsoncontaining{ "extends": "dtslint/dt.json" }.What is the current behavior?
https://codesandbox.io/s/r555ro878p
If you open that sandbox and wait for a compiler to catch up, you see that
TextReturningComponenthas an error. It is expectingReactElement<any> | nullto be returned.What is the expected behavior?
Based on the blog post it should be possible to have a component like that. Is that correct?
Looking at the type definition for
rendermethod it has return typeReactNodewhich is correct. However, the SFC declaration looks like this...I tried changing the return type to
ReactNode. However, it generates bunch of errors. I am still pretty much rookie to TypeScript, so I am not sure how to fix these. Can someone help me with that?