TypeScript 和 React - 儿童类型?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/53688899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
TypeScript and React - children type?
提问by Asool
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]
[ts] JSX 元素类型“ReactNode”不是 JSX 元素的构造函数。类型 'undefined' 不能分配给类型 'ElementClass'。[2605]
How do I type this correctly?
我如何正确输入?
回答by Ridd
Just children: React.ReactNode
只是 children: React.ReactNode
回答by Karol Majewski
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.
为了<Aux>
在您的 JSX 中使用,它需要是一个返回ReactElement<any> | null
. 这就是功能组件的定义。
However, it's currently defined as a function that returns React.ReactNode
, which is a much wider type. As React typings say:
但是,它目前被定义为一个返回 的函数React.ReactNode
,这是一个更广泛的类型。正如 React 类型所说:
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
Make sure the unwanted types are neutralized by wrapping the returned value into React Fragment (<></>
):
通过将返回值包装到 React Fragment ( <></>
)中,确保消除不需要的类型:
const aux: React.FC<AuxProps> = props =>
<>{props.children}</>;
回答by sunknudsen
This is what worked for me:
这对我有用:
interface Props {
children: JSX.Element[] | JSX.Element
}
EditI would recommend using children: React.ReactNode
instead now.
编辑我建议children: React.ReactNode
现在使用。
回答by jsina
you can declare your component like this:
你可以像这样声明你的组件:
const MyComponent: React.FunctionComponent = (props) => {
return props.children;
}
回答by Mike S
From the TypeScript site: https://github.com/Microsoft/TypeScript/issues/6471
来自 TypeScript 站点:https: //github.com/Microsoft/TypeScript/issues/6471
The recommended practice is to write the props type as {children?: any}
推荐的做法是将 props 类型写为 {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.
这里有关于后续问题的更长讨论:https: //github.com/Microsoft/TypeScript/issues/13618,但 any 方法仍然有效。
回答by ford04
children: React.ReactNode
is a bad idea, if you want children
to have a stronger type.
children: React.ReactNode
是个坏主意,如果你想要children
一个更强的类型。
You can assign almost anythingto ReactNode
, it behaves like the type {} | undefined | null
. Given you want an array of ReactElement
children for Aux
, a better idea is to use:
您几乎可以将任何内容分配给ReactNode
,它的行为类似于 type {} | undefined | null
。鉴于您想要一组ReactElement
儿童 for Aux
,一个更好的主意是使用:
interface AuxProps {
children: React.ReactElement[] // or JSX.Element[]
}
This type only allows an arrayof children and e.g. prevents string
as child- ReactNode
would just ignore it. Typed children
are also useful, if anything other than an JSX expression is passed, like a function to enable Render Props.
这种类型只允许一个孩子的数组,例如防止string
作为孩子-ReactNode
将忽略它。children
如果传递 JSX 表达式以外的任何内容,则键入也很有用,例如启用Render Props的函数。
Current TS limitationis that the return type in function components is limited to JSXElement | null
(ReactJS allows more). In edge cases you can either use a fragment or cast (see also Karol Majewski's answer):
当前的TS 限制是函数组件中的返回类型仅限于JSXElement | null
(ReactJS允许更多)。在极端情况下,您可以使用片段或演员表(另请参阅 Karol Majewski 的回答):
const Aux = (props: AuxProps) => <>props.children</>;
回答by Nickofthyme
The generalway to find any type is by example. The beauty of typescript is that you have access to alltypes, so long as you have the correct @types/
files.
查找任何类型的一般方法是通过示例。打字稿的美妙之处在于您可以访问所有类型,只要您拥有正确的@types/
文件。
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 />
?
为了自己回答这个问题,我只是想到了一个具有children
prop的组件 react 使用。想到的第一件事是什么?怎么样<div />
?
All you need to do is open vscodeand create a new .tsx
file in a react project with @types/react
.
您需要做的就是打开vscode并.tsx
在 react 项目中创建一个新文件@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[]
).
将鼠标悬停在children
道具上会显示类型。你知道什么——它的类型是ReactNode
(不需要ReactNode[]
)。
Then if you click into the type definition it brings you straight to the definition of children
coming from DOMAttributes
interface.
然后,如果您单击类型定义,它会直接将您带到children
来自DOMAttributes
接口的定义。
// 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 :)
注意:这个过程应该用于查找任何未知类型!他们都在那里等着你找到他们:)
回答by Denis
As a type that contains children, I'm using:
作为包含子项的类型,我正在使用:
type ChildrenContainer = Pick<JSX.IntrinsicElements["div"], "children">
This children container type is generic enough to support all the different cases and also aligned with the ReactJS API.
这种子容器类型足够通用,可以支持所有不同的情况,并且与 ReactJS API 保持一致。
So, for your example it would be something like:
因此,对于您的示例,它将类似于:
const layout = ({ children }: ChildrenContainer) => (
<Aux>
<div>Toolbar, SideDrawer, Backdrop</div>
<main>
{children}
</main>
<Aux/>
)
回答by Tim Iles
These answers appear to be outdated - React now has a built in type PropsWithChildren<{}>
. It is defined similarly to some of the correct answers on this page:
这些答案似乎已经过时——React 现在有一个内置的 type PropsWithChildren<{}>
。它的定义类似于此页面上的一些正确答案:
type PropsWithChildren<P> = P & { children?: ReactNode };
type PropsWithChildren<P> = P & { children?: ReactNode };
回答by Dinesh Pandiyan
React components should have a single wrapper node or return an array of nodes.
React 组件应该有一个单一的包装节点或返回一个节点数组。
Your <Aux>...</Aux>
component has two nodes div
and main
.
您的<Aux>...</Aux>
组件有两个节点div
和main
.
Try to wrap your children in a div
in Aux
component.
尝试将您的孩子包裹在一个div
inAux
组件中。
import * as React from 'react';
export interface AuxProps {
children: React.ReactNode
}
const aux = (props: AuxProps) => (<div>{props.children}</div>);
export default aux;