JSX 元素类型没有任何构造或调用签名

JSX 元素类型没有任何构造或调用签名

JSX element type does not have any construct or call signatures

当我们尝试将元素或 React 组件作为 props 传递给另一个组件但输入错误的 prop 时,会出现错误“JSX 元素类型没有任何构造或调用签名”。

要解决错误,请使用React.ElementType类型。

jsx 元素没有任何构造或调用签名

下面是错误如何发生的示例。

应用程序.tsx
import React from 'react'; interface Props { comp: JSX.Element; } const Wrapper: React.FunctionComponent<Props> = props => { const {comp: Comp} = props; // ⛔️ JSX element type 'Comp' does not have any construct or call signatures.ts(2604) return ( <div> <Comp name="James" /> </div> ); }; const App: React.FunctionComponent = () => { const heading = ({name}: {name: string}) => <h2>Hello {name}</h2>; return ( <div> <Wrapper comp={heading} /> </div> ); }; export default App;

我们试图将一个 React 组件作为 prop 传递给该Wrapper组件,但已将其键入为JSX.Element.

输入道具为React.ElementType

要解决该错误,请将 prop 键入 as React.ElementType

应用程序.tsx
import React from 'react'; interface Props { comp: React.ElementType; // 👈️ type it as React.ElementType } const Wrapper: React.FunctionComponent<Props> = props => { // 👇️ component names must start with capital letter const {comp: Comp} = props; return ( <div> <Comp name="James" /> </div> ); }; const App: React.FunctionComponent = () => { // 👇️ takes a name prop const heading = ({name}: {name: string}) => <h2>Hello {name}</h2>; return ( <div> <Wrapper comp={heading} /> </div> ); }; export default App;
请注意,React.ElementType可以为元素期望的道具类型传递一个泛型。

在这个例子中,我们必须向它传递一个具有name类型属性的对象string,因为这是组件采用的属性heading

应用程序.tsx
import React from 'react'; interface Props { // ✅ explicitly type props comp takes comp: React.ElementType<{name: string}>; } const Wrapper: React.FunctionComponent<Props> = props => { // 👇️ component names must start with a capital letter const {comp: Comp} = props; return ( <div> <Comp name="James" /> </div> ); }; const App: React.FunctionComponent = () => { const heading = ({name}: {name: string}) => <h2>Hello {name}</h2>; return ( <div> <Wrapper comp={heading} /> </div> ); }; export default App;

现在我们显式地键入了元素在使用时采用的道具comp这有助于我们在将道具传递给组件时利用我们的 IDE 进行自动完成。

使用React.ComponentType来解决错误

我们也可以使用React.ComponentType,但是我们需要输入道具。

应用程序.tsx
import React from 'react'; interface Props { // 👇️ now using React.ComponentType 👇️ comp: React.ComponentType<{name: string}>; } const Wrapper: React.FunctionComponent<Props> = props => { // 👇️ component names must start with a capital letter const {comp: Comp} = props; return ( <div> <Comp name="James" /> </div> ); }; const App: React.FunctionComponent = () => { const heading = ({name}: {name: string}) => <h2>Hello {name}</h2>; return ( <div> <Wrapper comp={heading} /> </div> ); }; export default App;

泛型 inReact.ComponentType不默认为any类型,因此我们需要显式键入 props。

将 JSX 元素作为 props 传递给组件

如果您需要将 JSX 元素作为 props 传递给组件,而不是实际组件,那么JSX.Element是正确的类型。

应用程序.tsx
import React from 'react'; interface Props { // 👇️ using JSX.Element type comp: JSX.Element; } const Wrapper: React.FunctionComponent<Props> = props => { const {comp: Comp} = props; // 👇️ use as {Comp} return <div>{Comp}</div>; }; const App: React.FunctionComponent = () => { const Heading = ({name}: {name: string}) => <h2>Hello {name}</h2>; // 👇️ we are passing an actual JSX element // because we didn't pass it as comp={Heading} return ( <div> <Wrapper comp={<Heading name="James" />} /> </div> ); }; export default App;

我们输入compprop as 是JSX.Element因为我们将实际的 JSX 元素(不是组件)传递给Wrapper组件。

我们正在传递一个 JSX 元素,因为我们传递的是 ascomp={<Heading />}
而不是
comp={(props) => <h2>Hello world</h2>}

请注意,在第一种情况下,我们传递了一个 JSX 元素 prop,而在第二种情况下,我们传递了一个返回 JSX 元素(功能组件)的函数。

我们不应该尝试在我们的组件中使用 JSX 元素作为组件Wrapper
,例如不要做
<Comp />,而是做{Comp}

我们没有传递一个实际的组件作为 prop,我们传递了一个 JSX 元素,所以它不应该被用作一个组件。

如果将多个子元素传递给采用单个 的组件
JSX.Element,则会出现错误
This JSX tag’s children prop expects single child of type Element, but multiple children were provided

更新你的 React.js 类型

如果之前的建议都没有帮助,请尝试通过运行以下命令来更新 React 类型的版本。

# 👇️ with NPM npm install react@latest react-dom@latest npm install --save-dev @types/react@latest @types/react-dom@latest # ---------------------------------------------- # 👇️ with YARN yarn add react@latest react-dom@latest yarn add @types/react@latest @types/react-dom@latest --dev

我已经写了一篇关于
如何正确更新 React.js 类型的详细指南。

额外资源

您可以通过查看以下教程来了解有关相关主题的更多信息: