首页 > 解决方案 > 如何在 TypeScript React 组件中返回字符串或 JSX 元素?

问题描述

我收到了这个奇怪的 TypeScript 错误:

import React from 'react'

type Props = {
  children: string
}

const Container = (props: Props) => {
  const isNew = true // make an api call...

  if (isNew) {
    return <NewContainer {...props} />
  } else {
    return <OldContainer {...props} />
  }
}

const NewContainer = ({ children }: Props) => {
  const isSpecial = useIsSpecial()

  if (!children) {
    return null
  }

  if (!isSpecial) {
    return children
  }

  return <a>{children}</a>
}

const OldContainer = ({ children }: Props) => {
  const isSpecial = useIsSpecial()

  if (!children) {
    return null
  }

  if (!isSpecial) {
    return children
  }

  return <a>{children}</a>
}

那些被这样使用:

<Container>foo</Children>

然后我得到这些打字稿错误:

'NewContainer' cannot be used as a JSX component.
  Its return type 'string | Element' is not a valid JSX element.
    Type 'string' is not assignable to type 'Element'.
'OldContainer' cannot be used as a JSX component.
  Its return type 'string | Element' is not a valid JSX element.
    Type 'string' is not assignable to type 'Element'.

如果我删除if (!isSpecial) return children,并将其更改为if (!isSpecial) return <span>{children}</span>,它工作正常。为什么它不允许我返回一个字符串?如何在 TypeScript 中解决这个问题?

标签: javascriptreactjstypescript

解决方案


TypeScript 的 React 类型不正确,不允许string作为组件类型的返回值。

一个 React 组件可以返回以下类型(一个 React 节点):

  • 无效的
  • 布尔值
  • 数字
  • 细绳
  • 反应元素
  • 反应门户
  • 数组(反应节点或未定义)

您可以轻松地运行下面的代码片段来测试它并观察组件是否正确呈现。

function HelloWorld() { return "Hello, World!"; }
ReactDOM.render(React.createElement(HelloWorld), document.getElementById("root"));
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<div id="root"></div>

您还可以注意到运行也可以ReactDOM.render("Hello, World!", ...),因为renderReact DOM 的功能需要一个有效的 React 节点,并且string就是这样。

但是您也可以使用包的isNode功能prop-typesFlow 的React$Node类型定义作为参考,以验证 React Node 类型接受什么,这两种类型定义都是由Facebook Meta 本身创建的。

TypeScript 维护人员似乎对修复此问题以及ReactNode错误接受的不正确类型不感兴趣undefined,因此您只能求助于解决方法,例如将文本包装到 Fragment 中,如其他评论中所述。


推荐阅读