reactjs - Typescript React forwardRef Birleşim/Genel Element ile


Bir div veya button elementi olabilen bir öğeyi uygulamaya çalışıyorum

type customElement = HTMLDivElement | HTMLDivElement   .....

const Element = React.forwardRef<customElement, somePropInterface>((props,ref)=>{
  if(someCase){
   return <div ref={ref}
  }else if(someCase2){
   return <button ref={ref}
  }else{
   return <a ref={ref}
  }
})

veya Genel durum

const Element = React.forwardRef((props,ref)=>{
  return <T ref={ref}/> // element with T...
})

Sorun, her durum için (div, a, button...) TypeScript'te React.ref'i tip güvenli hale getirmenin kolay olmaması.

Özel tip koruyucu kullanmayı denedim ama her öğe için neye bakmam gerektiğinden emin değilim

function isDivRef(
  ref: React.Ref<HTMLDivElement>,
  element: "div" | "button"
): ref is React.Ref<HTMLDivElement> {
  return ?????
}

Cevap #1

Üzerinde çalıştığım bir projede aynı sorunla karşılaşıyordum. Birkaç farklı birleşim türü kombinasyonunu denedikten sonra, deneme yanılma yoluyla, React.forwardRef ile birden fazla tür kullanmak için birleşim (union) yerine kesişim (intersection) kullanmanın gerektiğini öğrendim. Bu şekilde:

const Element = React.forwardRef<HTMLAnchorElement & HTMLButtonElement, Props>(
  (props, ref) => {
    if (...) {
      return <a ref={ref} ... />
    }
    return <button ref={ref} ... />
  }
);

İlgili makaleler