打字脚本错误:类型 'ReactNode' 上不存在属性'children'


export const PageViewTracker = ({ children }: ReactNode): ReactElement => {
usePageView();
return children;
};

问题:

此函数返回错误 »属性'子项'在类型'ReactNode'«上不存在

我的解决方案:

我尝试了几种类型,但只有任何不是我想要的作品。通常我使用ReactNode作为儿童道具,它工作得很好。在这种情况下,TypeScript 似乎有问题。

React>=18

在 React 18 中,FunctionalComponent接口已更改为:

interface FunctionComponent<P = {}> {
(props: P, context?: any): ReactElement<any, any> | null;
propTypes?: WeakValidationMap<P> | undefined;
contextTypes?: ValidationMap<any> | undefined;
defaultProps?: Partial<P> | undefined;
displayName?: string | undefined;
}

请注意,在 React 18 之后,FunctionalComponent 的props类型省略了PropsWithChildren类型,这意味着您必须自己包含children道具:

interface Props {
children: React.ReactNode;
}
export const PageViewTracker: React.FC<Props> = ({ children }) => {
}

他们删除隐式children道具的原因可以在这里找到。(来源于 React 18 的类型定义发行说明(。

PropsWithChildren类型在 React 的类型中仍然可用,所以如果你仍然想像 React 18 之前的版本一样选择children作为道具,你仍然可以这样做:

import { PropsWithChildren } from 'react';
interface Props {
foo: string;
}
export const PageViewTracker: React.FC<PropsWithChildren<Props>> = ({ children, foo }) => {
}

PropsWithChildren的类型定义为:

type PropsWithChildren<P = unknown> = P & { children?: ReactNode | undefined };
<小时 />

反应 <=17

您收到该错误的原因是因为您将"ReactNode"接口提供给对象({}: Type(。children本身的类型为 ReactNode:

type PropsWithChildren<P> = P & { children?: ReactNode };

您应该为您的PageViewTracker提供FunctionComponent(或其别名FC(类型。

export const PageViewTracker: React.FC = ({ children }) => {
...
}

它具有以下界面:

interface FunctionComponent<P = {}> {
(props: PropsWithChildren<P>, context?: any): ReactElement | null;
propTypes?: WeakValidationMap<P>;
contextTypes?: ValidationMap<any>;
defaultProps?: Partial<P>;
displayName?: string;
}

因此,默认情况下,它接受类型为"ReactNode"的childrenprop。

重要说明:在 react 18.0.0 之后,它们会让你在每个 FC 接口中包含子项。

interface MyButtonProps {
color: string;
children?: React.ReactNode;
}

然后你可以像旧版本一样传递道具。

const Button:React.FC<MyButtonProps> = (props) => {
//use children with {props.children} just like before  
}

从文档

对于"@types/反应":"17.0.43",或小于 18

import { FunctionComponent } from "react";

const BaseLayout: FunctionComponent = ({ children }) => {
return (
<>      
</>
);
};
export default BaseLayout;

对于"@types/反应"> 18

interface BaseLayoutProps {
children?: ReactNode;
}
const BaseLayout: FunctionComponent<BaseLayoutProps> = ({ children }) => {
return (
<>          
</>
);
};

但在某些情况下,您仍然需要使用FunctionComponent.例如:

interface ArtListProps {
arts: Art[];
children: FunctionComponent;
}
export default function ArtList({ arts, children }: ArtListProps) {
return (
<section className="grid md:grid-cols-1 lg:grid-cols-2 gap-4 mb-5">
{/* this is called render prop */}
{arts.map((art) => children(art))}
</section>
);
}

如果您传递ReactNode,则会收到错误"类型ReactNode不可调用">

你可以简单地这样写:

export const PageViewTracker = ({ children }: {children: ReactNode}): ReactElement => {
usePageView();
return children;
};

请注意,我将({ children }: ReactNode)更改为({ children }: {children: ReactNode})

import React from 'react';
interface Props {
children?: React.ReactNode;
}
export const MenuLateral: React.FC<Props> = ({ children }) => {
return (
<>

{children}
</>
);
};

正如丹在他的一条推文中提到的, "如果您在将 @types/react 升级到 18.0.0 时收到有关childrenprop 的 TypeScript 错误,修复程序如下所示。你需要在 props 类型中将它们声明为常规道具,并使用 React.ReactNode 类型。

反应 18

你可以在这里查看他的推文:https://twitter.com/dan_abramov/status/1512833611401150474

或此处的堆栈溢出线程: React 18 TypeScript children FC

你可以试试这个:

import { ReactNode } from "react";
export const PageViewTracker= ( { children }: {children: ReactNode} ) => {
usePageView();
return children;
};

您可以在泛型类型参数中批注它的类型:

import React, {ReactNode} from "react";
const Hello: React.FC<{ children: ReactNode }> = ({children}) => {
return <React.Fragment>
Hello {children}
</React.Fragment>;
}
import Navbar from "../Navbar/Navbar";
interface Layout {
children?: ReactNode;
}
const Layout: React.FC<Layout> = ({ children }) => {
return (
<>
<Navbar />
<main>{children}</main>
</>
);
};
export default Layout;

相关内容

  • 没有找到相关文章

最新更新