[Question] JSX.Element vs React.ReactNode once again
ivan-kleshnin opened this issue ยท 7 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 | nullWhat 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.ElementThis 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.