javascript - Eğer bir dizi ise çocukları veya çocuklar haritasını döndürürken any türünü doğru şekilde nasıl değiştiririm


Çocukların bir dizi olup olmadığını kontrol eden bir React fonksiyon bileşenim var. Eğer bir dizi değilse, onu döndürür. Aksi takdirde, çocuklar üzerinde map yapar ve bazı JSX döndürür.

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

Yapmak istediğim şey, 7. satırdaki any'yi değiştirmek. Mantıken bunu React.ReactNode olarak değiştirmek yeterli olur diye düşünüyorum, ama bu tip hatası veriyor:

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)

Bu hata mesajlarını doğru bir şekilde nasıl okuyacağım konusunda gerçekten bazı ipuçlarına ihtiyacım var.

Bu hata mesajını, dönüş tipini string|React.ReactNode olarak değiştirerek de atlatmaya çalıştım ve aynı hatayı bekledim çünkü sınırlı TypeScript bilgime göre React.ReactNode türüne string türü de dahildir.

Cevap #1

Bunu iki farklı yöntemle çözebildim.

  1. Fonksiyondan React.FC türünü kaldırın.
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. Tek çocuk dönüşünü bir Fragment içine sar.
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

Şimdi anladığım kadarıyla, bir React.FC yalnızca JSX.Element veya eşdeğeri bir değer döndürebilir. Children türü string, boolean, {} olabilir, ancak bu JSX.Element türüne uymaz. Yani, döndürülen türü kontrol etmek istiyorsam React.FC'yi kaldırmam gerekir, ya da React.FC kullanmak istiyorsam, çocukların dönüşünü bir fragment içine sarmam gerekir, böylece farklı çocuk türleri geçerli bir JSX.Element türü olarak doğru şekilde döner.

Cevap #2

@amaster'dan gelen çözümler iyi. Sadece hata mesajlarıyla ilgili kendi anlayışımı ekliyorum

Bence bu hatanın ne anlama geldiği bu

Hata, FC<Props> için beklenen dönüş türünün ReactElement<any, any> olduğunu söylüyor

Yani Type '({ children }: PropsWithChildren<Props>) => ReactNode' türü, FC<Props> türüne atanabilir değil. Bu, bir dönüş türü ReactNode olan bir şeyin, beklenen dönüş türü olan FC<Props> ile eşleşmediği anlamına gelir.

Ve Type 'ReactNode' is not assignable to type 'ReactElement<any, any>'. diyerek, beklenen ReactElement<any, any> yerine ReactNode'u return tipi olarak atamaya çalıştığınızı söylüyor.

İlgili makaleler