问题
I have a very simple functional component as follows:
import * as React from 'react';
export interface AuxProps {
children: React.ReactNode
}
const aux = (props: AuxProps) => props.children;
export default aux;
And another component:
import * as React from "react";
export interface LayoutProps {
children: React.ReactNode
}
const layout = (props: LayoutProps) => (
<Aux>
<div>Toolbar, SideDrawer, Backdrop</div>
<main>
{props.children}
</main>
<Aux/>
);
export default layout;
I keep on getting the following error:
[ts] JSX element type 'ReactNode' is not a constructor function for JSX elements. Type 'undefined' is not assignable to type 'ElementClass'. [2605]
How do I type this correctly?
回答1:
In order to use <Aux> in your JSX, it needs to be a function that returns ReactElement<any> | null. That's the definition of a function component.
However, it's currently defined as a function that returns React.ReactNode, which is a much wider type. As React typings say:
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
Make sure the unwanted types are neutralized by wrapping the returned value into React Fragment (<></>):
const aux: React.FC<AuxProps> = props =>
<>{props.children}</>;
回答2:
This is what worked for me:
interface Props {
children: JSX.Element[] | JSX.Element
}
回答3:
Just children: React.ReactNode
回答4:
From the TypeScript site: https://github.com/Microsoft/TypeScript/issues/6471
The recommended practice is to write the props type as {children?: any}
That worked for me. The child node can be many different things, so explicit typing can miss cases.
There's a longer discussion on the followup issue here: https://github.com/Microsoft/TypeScript/issues/13618, but the any approach still works.
回答5:
you can declare your component like this:
const MyComponent: React.FunctionComponent = (props) => {
return props.children;
}
回答6:
The general way to find any type is by example. The beauty of typescript is that you have access to all types, so long as you have the correct @types/ files.
To answer this myself I just thought of a component react uses that has the children prop. The first thing that came to mind? How about a <div />?
All you need to do is open vscode and create a new .tsx file in a react project with @types/react.
import React from 'react';
export default () => (
<div children={'test'} />
);
Hovering over the children prop shows you the type. And what do you know -- Its type is ReactNode (no need for ReactNode[]).
Then if you click into the type definition it brings you straight to the definition of children coming from DOMAttributes interface.
// node_modules/@types/react/index.d.ts
interface DOMAttributes<T> {
children?: ReactNode;
...
}
Note: This process should be used to find any unknown type! All of them are there just waiting for you to find them :)
回答7:
React components should have a single wrapper node or return an array of nodes.
Your <Aux>...</Aux> component has two nodes div and main.
Try to wrap your children in a div in Aux component.
import * as React from 'react';
export interface AuxProps {
children: React.ReactNode
}
const aux = (props: AuxProps) => (<div>{props.children}</div>);
export default aux;
来源:https://stackoverflow.com/questions/53688899/typescript-and-react-children-type