0Pricing
TypeScript Academy · Lección

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 T a React.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.Element

Ejemplos 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 T a React.ElementType.
  • Use Omit para resolver las colisiones entre nombres de props.
  • Reenvíe la ref con forwardRef y asígnele el tipo React.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.

← Volver a TypeScript Academy