Componentes polimórficos y props as
Cree un componente Button polimórfico con una prop as; combine props intrínsecas del DOM y tipifique refs mediante forwardRef y ComponentRef .
Componentes polimórficos y props as es una lección gratuita de TypeScript Academy en CoddyKit. Esta es la lección 1 de 1. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de TypeScript Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de TypeScript Academy incluye 1 lecciones en total.
Introducción
Objetivo: Cree un único Button polimórfico que pueda renderizarse como button, a o cualquier elemento mediante una prop as, conservando los tipos de las props y de la ref.
- Restrinja
TaReact.ElementType - Combine las props de forma segura
- Tipar la ref reenviada
Tipos base
Empiece con OwnProps y una utilidad PolymorphicProps<T, P> que combine las props intrínsecas de T con las suyas.
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 polimórfico
El componente usa button de forma predeterminada, pero acepta as. El tipo de la ref cambia con T (por ejemplo, HTMLAnchorElement para "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.ElementEjemplos de uso
Cuando as="a", las props intrínsecas como href están disponibles y la ref se tipa como 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>
)
}Variantes
Puede envolver el componente polimórfico y conservar su flexibilidad. Use ComponentProps<typeof Button> para heredar sus 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>
)
}Consejos
Consejos:
- Restrinja
TaReact.ElementType. - Use
Omitpara resolver las colisiones entre nombres de props. - Reenvíe la ref con
forwardRefy asígnele el tipoReact.ComponentRef<T>.
Comprobación del tipado polimórfico
Comprobación rápida: ¿qué tipado modela correctamente un componente polimórfico que reenvía su ref?
Resumen
Resumen: Ha creado un Button polimórfico con una prop as, ha combinado de forma segura las props intrínsecas y ha tipado la ref reenviada para que los consumidores obtengan un autocompletado correcto.
Preguntas frecuentes
¿La lección «Componentes polimórficos y props as» es gratis?
Sí — el texto completo de «Componentes polimórficos y props as» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de TypeScript Academy, actualiza a CoddyKit PRO. El curso de TypeScript Academy incluye 1 lecciones en total.
¿Qué aprenderé en «Componentes polimórficos y props as»?
Cree un componente Button polimórfico con una prop as; combine props intrínsecas del DOM y tipifique refs mediante forwardRef y ComponentRef . Practicas TypeScript Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar TypeScript Academy?
No se requiere experiencia previa. TypeScript Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 1.
¿Cuánto tiempo toma la lección «Componentes polimórficos y props as»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de TypeScript Academy?
Sí. Cada lección de TypeScript Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.