# TypeScript

## React Node vs React JSX Element

* `JSX Element` is an element that react.createElement is allowed to create, simply the object of virtual dom
* `React.ReactNode` means value of a component, but also a list of jsx elements

```typescript
declare namespace React {
  type ReactNode =
    | ReactElement
    | string
    | number
    | ReactFragment
    | ReactPortal
    | boolean
    | null
    | undefined;
}
```

<pre class="language-typescript"><code class="lang-typescript">const node: React.ReactNode = &#x3C;div />;
const node2: React.ReactNode = "hello world";
const node3: React.ReactNode = 123;
const node4: React.ReactNode = undefined;
const node5: React.ReactNode = null;

const node6: JSX.Element = "hello world";
<strong>// Error : Type 'string' is not assignable to type 'Element'.
</strong></code></pre>

## Best Practice & Use Cases

```typescript
export declare interface AppProps {
  children?: React.ReactNode; // best, accepts everything React can render
  childrenElement: React.JSX.Element; // A single React element
  style?: React.CSSProperties; // to pass through style props
  onChange?: React.FormEventHandler<HTMLInputElement>; // form events! the generic parameter is the type of event.target
  //  more info: https://react-typescript-cheatsheet.netlify.app/docs/advanced/patterns_by_usecase/#wrappingmirroring
  props: Props & React.ComponentPropsWithoutRef<"button">; // to impersonate all the props of a button element and explicitly not forwarding its ref
  props2: Props & React.ComponentPropsWithRef<MyButtonWithForwardRef>; // to impersonate all the props of MyButtonForwardedRef and explicitly forwarding its ref
}
```

## References

{% embed url="https://react-typescript-cheatsheet.netlify.app/docs/basic/setup" %}
