[Question] JSX.Element vs React.ReactNode once again
ivan-kleshnin opened this issue · comments
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?
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
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.
ahh. gotcha.
@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.
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.
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?
for class components I can use ReactNode to type props and children
minor correction/caveat but yeah.