TypeScript Academy · Lektion

Polymorfa komponenter och as-props

Bygg en polymorf Button-komponent med en as-prop, slå samman inbyggda DOM-props och typa refs med forwardRef och ComponentRef .

Lektion 1 av 18 steg

Polymorfa komponenter och as-props är en gratis lektion i TypeScript Academy på CoddyKit. Detta är lektion 1 av 1. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för TypeScript Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i TypeScript Academy innehåller totalt 1 lektioner.

Introduktion

Mål: Skapa en enda polymorf Button som kan renderas som button, a eller vilket element som helst via en as-prop – samtidigt som prop- och ref-typerna bevaras.

  • Begränsa T till React.ElementType
  • Slå ihop props på ett säkert sätt
  • Typa den vidarebefordrade refen

Bastyper

Börja med OwnProps och ett verktyg PolymorphicProps<T, P> som slår ihop inbyggda props för T med dina egna.

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)

Polymorf Button

Komponenten använder button som standard men accepterar as. Ref-typen ändras med T (till exempel HTMLAnchorElement för "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

Användningsexempel

När as="a" används blir inbyggda props som href tillgängliga och refen typas som 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>
  )
}

Varianter

Du kan kapsla in den polymorfa komponenten och ändå behålla flexibiliteten. Använd ComponentProps<typeof Button> för att ärva dess 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>
  )
}

Tips

Tips:

  • Begränsa T till React.ElementType.
  • Använd Omit för att lösa kollisioner mellan propnamn.
  • Vidarebefordra refen med forwardRef och typa den som React.ComponentRef<T>.

Kontroll av polymorf typning

Snabb kontroll: Vilken typning modellerar korrekt en polymorf komponent som vidarebefordrar sin ref?

Sammanfattning

Sammanfattning: Du byggde en polymorf Button med en as-prop, slog säkert ihop inbyggda props och typade den vidarebefordrade refen så att användarna får korrekt intellisense.

Gratis att börja

Lär dig TypeScript med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
101
Lektioner
352

Vanliga frågor

Är lektionen ”Polymorfa komponenter och as-props” gratis?

Ja – hela texten till ”Polymorfa komponenter och as-props” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i TypeScript Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i TypeScript Academy innehåller totalt 1 lektioner.

Vad lär jag mig i ”Polymorfa komponenter och as-props”?

Bygg en polymorf Button-komponent med en as-prop, slå samman inbyggda DOM-props och typa refs med forwardRef och ComponentRef . Ni övar på TypeScript Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig TypeScript Academy?

Du behöver inga förkunskaper. Utbildningen i TypeScript Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 1.

Hur lång tid tar lektionen ”Polymorfa komponenter och as-props”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här TypeScript Academy-lektionen?

Ja. Varje TypeScript Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

← Tillbaka till TypeScript Academy