0Pricing
TypeScript Academy · Lezione

Componenti polimorfici; props as

Crei un componente Button polimorfico con una prop as; unisca le props intrinseche/DOM; tipizzi le refs con forwardRef e ComponentRef .

Componenti polimorfici; props as è una lezione TypeScript Academy gratuita su CoddyKit. Questa è la lezione 1 di 1. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento TypeScript Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso TypeScript Academy include 1 lezioni in totale.

Introduzione

Obiettivo: creare un unico Button polimorfico che possa eseguire il rendering come button, a o qualsiasi elemento tramite una prop as, mantenendo i tipi delle props e della ref.

  • Vincolare T a React.ElementType
  • Unire le props in modo sicuro
  • Tipizzare la ref inoltrata

Tipi di base

Inizi con OwnProps e con un'utility PolymorphicProps<T, P> che unisce le props intrinseche per T alle proprie.

import React from "react"

type OwnProps = {
  variant?: "solid" | "outline"
  children: React.ReactNode
}

type PolymorphicProps<T extends React.ElementType, P> = {
  as?: T
} & P & Omit<React.ComponentPropsWithoutRef<T>, keyof P | "as">

// Example: Omit avoids prop collisions (e.g., our OwnProps vs intrinsic props)

Button polimorfico

Il componente utilizza button come valore predefinito, ma accetta as. Il tipo della ref cambia con T (ad es. HTMLAnchorElement per "a").

import React, { forwardRef } from "react"

type OwnProps = { variant?: "solid" | "outline"; children: React.ReactNode }

type PolymorphicProps<T extends React.ElementType, P> = { as?: T } & P & Omit<React.ComponentPropsWithoutRef<T>, keyof P | "as">

const ButtonInner = <T extends React.ElementType = "button">(
  { as, variant = "solid", children, ...rest }: PolymorphicProps<T, OwnProps>,
  ref: React.ForwardedRef<React.ComponentRef<T>>
) => {
  const Component = (as || "button") as React.ElementType
  const style = variant === "outline" ? { border: "1px solid #333", padding: 8 } : { background: "#2563eb", color: "white", padding: 8, borderRadius: 6 }
  return <Component ref={ref} style={style} {...rest}>{children}</Component>
}

export const Button = forwardRef(ButtonInner) as <T extends React.ElementType = "button">(
  props: PolymorphicProps<T, OwnProps> & { ref?: React.Ref<React.ComponentRef<T>> }
) => JSX.Element

Esempi d'uso

Quando as="a", diventano disponibili props intrinseche come href e la ref viene tipizzata come HTMLAnchorElement.

import React, { useRef } from "react"
import { Button } from "./Button"

export default function App() {
  const btnRef = useRef<HTMLButtonElement>(null)
  const linkRef = useRef<HTMLAnchorElement>(null)

  return (
    <div style={{ display: "grid", gap: 8 }}>
      <Button ref={btnRef} onClick={() => alert("clicked")}>Save</Button>
      <Button as="a" ref={linkRef} href="#docs" variant="outline">Docs</Button>
    </div>
  )
}

Varianti

Può racchiudere il componente polimorfico mantenendone comunque la flessibilità. Utilizzi ComponentProps<typeof Button> per ereditare le sue props.

import React from "react"
import { Button } from "./Button"

export function DangerButton(props: Omit<React.ComponentProps<typeof Button>, "variant">) {
  return <Button {...props} style={{ background: "#dc2626", color: "white", padding: 8, borderRadius: 6 }} />
}

// Works with polymorphism too
export default function App() {
  return (
    <div style={{ display: "grid", gap: 8 }}>
      <DangerButton>Delete</DangerButton>
      <DangerButton as="a" href="#confirm">Delete link</DangerButton>
    </div>
  )
}

Suggerimenti

Suggerimenti:

  • Vincoli T a React.ElementType.
  • Utilizzi Omit per risolvere le collisioni tra i nomi delle props.
  • Inoltri la ref con forwardRef e la tipizzi come React.ComponentRef<T>.

Verifica della tipizzazione polimorfica

Verifica rapida: quale tipizzazione modella correttamente un componente polimorfico che inoltra la propria ref?

Riepilogo

Riepilogo: ha creato un Button polimorfico con una prop as, ha unito in sicurezza le props intrinseche e ha tipizzato la ref inoltrata, così i consumer ricevono un completamento IntelliSense corretto.

Domande Frequenti

La lezione «Componenti polimorfici; props as» è gratuita?

Sì — il testo completo di «Componenti polimorfici; props as» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso TypeScript Academy, passa a CoddyKit PRO. Il corso TypeScript Academy include 1 lezioni in totale.

Cosa imparerò in «Componenti polimorfici; props as»?

Crei un componente Button polimorfico con una prop as; unisca le props intrinseche/DOM; tipizzi le refs con forwardRef e ComponentRef . Eserciti TypeScript Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare TypeScript Academy?

Non è richiesta alcuna esperienza precedente. TypeScript Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 1.

Quanto tempo richiede la lezione «Componenti polimorfici; props as»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione TypeScript Academy?

Sì. Ogni lezione TypeScript Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

← Torna a TypeScript Academy