首页 > 解决方案 > 如果数组返回子级或子级映射时如何正确替换任何类型

问题描述

我有一个 React 函数组件来检查 children 是否是一个数组。如果它不是数组,则返回它。否则它会映射孩子并返回一些 JSX。

import React from 'react'

interface Props {
  children: React.ReactNode
}

const LineBreak: React.FC<Props> = ({ children }): any => {
  if (!Array.isArray(children)) return children
  return (
    <>
      {children.map((child, i, arr) => {
        if (i + 1 === arr.length) return child
        return <>{child}<br /></>
      })}
    </>
  )
}

export default LineBreak

我想做的是替换第any7 行。从逻辑上讲,我认为将其更改为React.ReactNode就足够了,但这会引发类型错误:

Type '({ children }: PropsWithChildren<Props>) => ReactNode' is not assignable to type 'FC<Props>'.
  Type 'ReactNode' is not assignable to type 'ReactElement<any, any>'.
    Type 'string' is not assignable to type 'ReactElement<any, any>'.ts(2322)

我真的可以使用一些关于如何正确阅读这些错误消息的指针。

我还尝试通过将返回类型更改为string|React.ReactNode并预期相同的错误来绕过此错误消息,因为根据我有限的打字稿知识,React.ReactNode 包含类型字符串。

标签: javascriptreactjstypescripttypes

解决方案


我能够用两种不同的方法解决这个问题。

  1. 从函数中删除 React.FC 类型。
import React from 'react'

interface Props {
  children: React.ReactNode
}

const LineBreak = ({children}: Props): React.ReactNode => {
  if (!Array.isArray(children)) return children
  return (
    <>
      {children.map((child, i, arr) => {
        if (i + 1 === arr.length) return child
        return <>{child}<br /></>
      })}
    </>
  )
}

export default LineBreak
  1. 将单个子返回包裹在 Fragment 内。
import React from 'react'

interface Props {
  children: React.ReactNode
}

const LineBreak: React.FC<Props> = ({children}): JSX.Element => {
  if (!Array.isArray(children)) return <>{children}</>
  return (
    <>
      {children.map((child, i, arr) => {
        if (i + 1 === arr.length) return child
        return <>{child}<br /></>
      })}
    </>
  )
}

export default LineBreak

根据我现在的理解,React.FC 只能是 JSX.Element 或等效的返回类型。虽然 children 可能是不符合 JSX.Element 类型的字符串、布尔值、{} 类型。因此,如果我想控制返回类型,那么我必须删除 React.FC,或者如果我想使用 React.FC,那么我需要将子项的返回包装在一个片段中,以便它正确返回各种子类型作为有效的 JSX.Element 类型。


推荐阅读