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

[Question] JSX.Element vs React.ReactNode once again #129

Closed
ivan-kleshnin opened this issue Jul 2, 2019 · 7 comments
Closed

[Question] JSX.Element vs React.ReactNode once again #129

ivan-kleshnin opened this issue Jul 2, 2019 · 7 comments
Assignees
Labels
good first issue Good for newcomers

Comments

@ivan-kleshnin
Copy link

ivan-kleshnin commented Jul 2, 2019

Hi. The Basic README claims that React.ReactNode is preferable to JSX.Element as a return value of a component because JSX.Element is a return type of React.createElement which is not, to put it simple, wide enough. Hovewer, when I attempt to use both to define the return type of a component, JSX.Element fits and React.ReactNode does not:

let C1 = (): JSX.Element => <div>test</div>
let c1 = <C1 />; // fine

let C2 = (): React.ReactNode => <div>test</div>
let c2 = <C2 />; // JSX Element type ReactNode is not a constructor function for JSX elements
// Type undefined is not assignable to type Element | null

What am I doing wrong?

@ivan-kleshnin ivan-kleshnin added the good first issue Good for newcomers label Jul 2, 2019
@ivan-kleshnin ivan-kleshnin changed the title JSX.Element vs React.ReactNode once again [Question] JSX.Element vs React.ReactNode once again Jul 2, 2019
@swyxio
Copy link
Collaborator

swyxio commented Jul 3, 2019

hmm @ferdaber is it viable to add undefined to ReactNode?

@ivan-kleshnin - fine question. but for my purposes, i dont bother explicitly typing it. i just let TS infer it since its so easy to see:

let C2 = () => <div>test</div>
let c2 = <C2 /> // c2: JSX.Element

@ferdaber
Copy link
Collaborator

ferdaber commented Jul 3, 2019

This specific case is not covered in the pitfalls section but is the same root cause as what is described in this section's "Minor Pitfalls" subsection: https://github.com/typescript-cheatsheets/react-typescript-cheatsheet#function-components.

You can't return anything other than a JSX expression or null in a function component (not applicable to render in class components), if you do-- you have to type assert it to any first. This is unfortunately a limitation of the compiler, and I don't think is being fixed any time soon.

@swyxio
Copy link
Collaborator

swyxio commented Jul 3, 2019

ahh. gotcha.

@swyxio swyxio closed this as completed Jul 3, 2019
@eps1lon
Copy link
Member

eps1lon commented Jul 3, 2019

@ivan-kleshnin Could you quote the section that claims ReactNode should be preferred over JSX.Element? I couldn't really find a section that implied this. If we have such a misleading section we should change it.

@swyxio
Copy link
Collaborator

swyxio commented Jul 3, 2019

its the "how to type children" section https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/blob/cc2ec67e0b36b7e838df8f2a54b4cd84df6c78cd/README.md#useful-react-prop-type-examples

its specifically for typing children, which is correct.

@ivan-kleshnin
Copy link
Author

ivan-kleshnin commented Jul 4, 2019

So, to underline, for class components I can use ReactNode and for functional components JSX.Element but it's easier to omit return type as it doesn't really add to the type safety. Right?

@swyxio
Copy link
Collaborator

swyxio commented Jul 5, 2019

for class components I can use ReactNode to type props and children

minor correction/caveat but yeah.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

4 participants