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
TaReact.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.ElementEsempi 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
TaReact.ElementType. - Utilizzi
Omitper risolvere le collisioni tra i nomi delle props. - Inoltri la ref con
forwardRefe la tipizzi comeReact.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.