//
Busca en todas las páginas de la documentación
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Define contratos de prop claros y seguros para tus componentes React usando interfaces y alias de tipo de TypeScript. Cubre props requeridas, props opcionales, children, y patrones de props comunes.
// Props básicos con campos requeridos y opcionales
type ButtonProps = {
label: string;
variant?: "primary" | "secondary" | "danger";
disabled?: boolean;
onClick: () => void;
};
export function Button({ label, variant = "primary", disabled = false, onClick }: ButtonProps) {
return (
<button className={`btn btn-${variant}`} disabled={disabled} onClick={onClick}>
{label}
</button>
);
}// Tipado de children
type CardProps = {
title: string;
children: React.ReactNode;
};
export function Card({ title, children }: CardProps) {
return (
<div className="card">
<h2>{title}</h2>
<div className="card-body">{children}</div>
</div>
);
}// Patrón render prop
type DataListProps<T> = {
items: T[];
renderItem: (item: T, index: number) => React.ReactNode;
};
export function DataList<T>({ items, renderItem }: DataListProps<T>) {
return <ul>{items.map((item, i) => <li key={i}>{renderItem(item, i)}</li>)}</ul>;
}// Uso
<Button label="Submit" onClick={() => console.log("clicked")} />
<Card title="Welcome"><p>Hello world</p></Card>
<DataList items={["a", "b"]} renderItem={(item) => <span>{item}</span>} />React.ReactNode es el tipo children más amplio. Acepta strings, números, elementos JSX, arrays, fragmentos, null, y undefined.React.ReactElement es más estrecho que ReactNode. Úsalo cuando específicamente necesites un elemento JSX (no un string o número).variant = "primary") funcionan perfectamente con props opcionales. TypeScript infiere el tipo estrechado dentro del cuerpo de la función."primary" | "secondary" te dan autocompletado y atrapan typos en tiempo de compilación.Extendiendo props de elementos HTML:
type InputProps = React.ComponentPropsWithoutRef<"input"> & {
label: string;
error?: string;
};
export function Input({ label, error, ...rest }: InputProps) {
return (
<div>
<label>{label}</label>
<input {...rest} />
{error && <span className="error">{error}</span>}
</div>
);
}Props con inyección de componentes:
type LayoutProps = {
as?: React.ElementType;
children: React.ReactNode;
className?: string;
};
export function Layout({ as: Component = "div", children, className }: LayoutProps) {
return <Component className={className}>{children}</Component>;
}type para props que usan uniones o intersecciones. Usa interface cuando necesites extends o quieras declaration merging.React.PropsWithChildren<T> es una abreviatura que añade children?: React.ReactNode a tu tipo.React.ComponentPropsWithRef<"div"> incluye el prop ref; ComponentPropsWithoutRef<"div"> lo excluye.React.FC añade un prop children implícito en tipos de React antiguos (pre-18). En tipos de React 18+, React.FC ya no incluye children implícitamente.JSX.Element rechazará strings, números, y arrays. Usa React.ReactNode a menos que tengas una razón específica....rest a un elemento DOM sin filtrar props personalizados causa advertencias de React sobre atributos DOM desconocidos.| Enfoque | Ventajas | Desventajas |
|---|---|---|
Alias type | Soporta uniones, intersecciones, tipos mapeados | Sin declaration merging |
interface | Extensible, patrón OOP familiar | No puede expresar tipos de unión directamente |
React.FC<Props> | Anotación de tipo de retorno explícita | Verboso, sin soporte para componentes genéricos |
| Tipos de props inline | Rápido para componentes desechables | Difícil de reutilizar o exportar |
PropsWithChildren | Abreviatura conveniente para children | Oculta el prop children de los lectores |
type cuando necesites uniones, intersecciones, o tipos mapeados.interface cuando necesites extends o declaration merging.type es suficiente y más flexible.ReactNode acepta strings, números, elementos JSX, arrays, fragmentos, null, y undefined.ReactElement solo acepta elementos JSX (no strings o números).ReactNode a menos que específicamente necesites restringir children a elementos JSX.type InputProps = React.ComponentPropsWithoutRef<"input"> & {
label: string;
error?: string;
};
function Input({ label, error, ...rest }: InputProps) {
return (
<div>
<label>{label}</label>
<input {...rest} />
{error && <span>{error}</span>}
</div>
);
}ComponentPropsWithoutRef<"element"> para obtener todos los props nativos.&.label o error se pasan al elemento HTML.type ButtonProps = {
variant?: "primary" | "secondary";
};
function Button({ variant = "primary" }: ButtonProps) {
// TypeScript estrecha variant a "primary" | "secondary" (no undefined)
}? en el tipo.children?: React.ReactNode a tu tipo.children de los lectores de la definición de tipo.children: React.ReactNode en el tipo para claridad.React.FC ya no incluye children implícitamente.children implícito.type DataListProps<T> = {
items: T[];
renderItem: (item: T, index: number) => React.ReactNode;
};React.ReactNode.type LayoutProps = {
as?: React.ElementType;
children: React.ReactNode;
};
function Layout({ as: Component = "div", children }: LayoutProps) {
return <Component>{children}</Component>;
}React.ElementType acepta etiquetas string ("div", "span") y tipos de componentes.Revisado por Chris St. John·Última actualización: 7 jul 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥