TypeScript
Beginner
1 min read
Typing React Components and Props
Example
import React, { type ReactNode } from "react";
// Basic typed component — direct param annotation (preferred)
interface ButtonProps {
label: string;
variant?: "primary" | "secondary" | "danger";
disabled?: boolean;
onClick?: () => void;
className?: string;
}
export function Button({
label,
variant = "primary",
disabled = false,
onClick,
className = "",
}: ButtonProps): React.ReactElement {
return (
<button
className={`btn btn-${variant} ${className}`}
disabled={disabled}
onClick={onClick}
>
{label}
</button>
);
}
// Discriminated union props — component variants
type AlertProps =
| { type: "success"; message: string }
| { type: "error"; message: string; retry?: () => void }
| { type: "warning"; message: string; dismissible?: boolean };
export function Alert(props: AlertProps): React.ReactElement {
const base = `alert alert-${props.type}`;
if (props.type === "error") {
return <div className={base}>{props.message} {props.retry && <button onClick={props.retry}>Retry</button>}</div>;
}
return <div className={base}>{props.message}</div>;
}
// Children prop
interface CardProps {
title: string;
children: ReactNode;
footer?: ReactNode;
}
export function Card({ title, children, footer }: CardProps) {
return (
<div className="card">
<h2>{title}</h2>
<div className="card-body">{children}</div>
{footer && <div className="card-footer">{footer}</div>}
</div>
);
}
Related Resources
TypeScript Reference
Complete tag & property list
TypeScript How-To Guides
Step-by-step practical guides
TypeScript Exercises
Practice what you've learned
More in TypeScript