From 9f83f5817a0840bb775af7aeb48a4ea7a02d07b3 Mon Sep 17 00:00:00 2001 From: chivalrousdev Date: Mon, 21 Dec 2020 02:18:14 +0800 Subject: [PATCH] add note on ReactNode edge case closes https://github.com/typescript-cheatsheets/react/issues/357 thank you @pomle --- .../getting-started/basic-type-examples.md | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/docs/basic/getting-started/basic-type-examples.md b/docs/basic/getting-started/basic-type-examples.md index 3372e58..8fb2366 100644 --- a/docs/basic/getting-started/basic-type-examples.md +++ b/docs/basic/getting-started/basic-type-examples.md @@ -60,8 +60,8 @@ export declare interface AppProps { children1: JSX.Element; // bad, doesnt account for arrays children2: JSX.Element | JSX.Element[]; // meh, doesn't accept strings children3: React.ReactChildren; // despite the name, not at all an appropriate type; it is a utility - children4: React.ReactChild[]; // better - children: React.ReactNode; // best, accepts everything + children4: React.ReactChild[]; // better, accepts array children + children: React.ReactNode; // best, accepts everything (see edge case below) functionChildren: (name: string) => React.ReactNode; // recommended function as a child render prop type style?: React.CSSProperties; // to pass through style props onChange?: React.FormEventHandler; // form events! the generic parameter is the type of event.target @@ -71,6 +71,33 @@ export declare interface AppProps { } ``` +
+ +Small `React.ReactNode` edge case + + +This code typechecks but has a runtime error: + +```tsx + +type Props = { + children: React.ReactNode; +} + +function Comp({children}: Props) { + return
{children}
; +} +function App() { + return {{}} // Runtime Error: Objects not valid as React Child! +} +``` + +This is because `ReactNode` includes `ReactFragment` which allows a `{}` type, which is [too wide](https://github.com/DefinitelyTyped/DefinitelyTyped/issues/37596#issue-480260937). Fixing this would break a lot of libraries, so for now you just have to be mindful that `ReactNode` is not absolutely bulletproof. + +[Thanks @pomle for raising this.](https://github.com/typescript-cheatsheets/react/issues/357) + +
+
JSX.Element vs React.ReactNode?