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 .
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
TtillReact.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.ElementAnvä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
TtillReact.ElementType. - Använd
Omitför att lösa kollisioner mellan propnamn. - Vidarebefordra refen med
forwardRefoch typa den somReact.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.
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.