如何在返回子项时正确替换类型 any 或返回子项映射时是否为数组

新手上路,请多包涵

我有一个 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

我想做的是替换第 7 行的 any 我逻辑上认为将其更改为 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 包含类型字符串。

原文由 amaster 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 363
2 个回答

@amaster 的解决方案很好。只是添加我对错误消息的理解

我认为这就是错误的含义

错误是说 FC<Props> 的预期返回类型是 ReactElement<any, any>

所以 Type '({ children }: PropsWithChildren<Props>) => ReactNode' is not assignable to type 'FC<Props>'. 意味着返回类型为ReactNode的东西与 FC<Props>

并且 Type 'ReactNode' is not assignable to type 'ReactElement<any, any>'. 是说您正在尝试将 ReactNode 分配为返回类型而不是预期的 ReactElement<any, any>

原文由 Moshe Sommers 发布,翻译遵循 CC BY-SA 4.0 许可协议

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

  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. 将单个子返回包裹在片段中。
 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 类型。

原文由 amaster 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题