//
Busque em todas as páginas da documentação
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Defina contratos de props claros e com segurança de tipo para seus componentes React usando interfaces e aliases de tipo do TypeScript. Cubra props obrigatórias, props opcionais, children e padrões comuns de props.
// Props básicas com campos obrigatórios e opcionais
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>
);
}// Tipando 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>
);
}// Padrão de 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="Enviar" onClick={() => console.log("clicado")} />
<Card title="Bem-vindo"><p>Olá mundo</p></Card>
<DataList items={["a", "b"]} renderItem={(item) => <span>{item}</span>} />React.ReactNode é o tipo mais amplo para children. Ele aceita strings, números, elementos JSX, arrays, fragments, null e undefined.React.ReactElement é mais restrito que ReactNode. Use-o quando você especificamente precisa de um elemento JSX (não uma string ou número).variant = "primary") funcionam perfeitamente com props opcionais. O TypeScript infere o tipo mais restrito dentro do corpo da função."primary" | "secondary" oferecem autocompletar e capturam erros de digitação em tempo de compilação.Estendendo 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 com injeção de componente:
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 usam uniões ou interseções. Use interface quando precisar de extends ou quiser a fusão de declarações.React.PropsWithChildren<T> é um atalho que adiciona children?: React.ReactNode ao seu tipo.React.ComponentPropsWithRef<"div"> inclui a prop ref; ComponentPropsWithoutRef<"div"> a exclui.React.FC adiciona uma prop children implícita nos tipos mais antigos do React (pré-18). Nos tipos do React 18+, React.FC não inclui mais children implicitamente.children como JSX.Element rejeitará strings, números e arrays. Use React.ReactNode a menos que tenha um motivo específico....rest em um elemento DOM sem filtrar props personalizadas causa avisos do React sobre atributos DOM desconhecidos.| Abordagem | Prós | Contras |
|---|---|---|
Alias type | Suporta uniões, interseções, tipos mapeados | Sem fusão de declarações |
interface | Extensível, padrão familiar de OOP | Não pode expressar tipos de união diretamente |
React.FC<Props> | Anotação explícita de tipo de retorno | Verboso, sem suporte a componentes genéricos |
| Tipos de props inline | Rápido para componentes descartáveis | Difícil de reutilizar ou exportar |
PropsWithChildren | Atalho conveniente para children | Oculta a prop children dos leitores |
type quando precisar de uniões, interseções ou tipos mapeados.interface quando precisar de extends ou fusão de declarações.type é suficiente e mais flexível.ReactNode aceita strings, números, elementos JSX, arrays, fragments, null e undefined.ReactElement aceita apenas elementos JSX (não strings ou números).ReactNode a menos que você precise especificamente 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 obter todas as props nativas.&.label ou error são passadas para o elemento HTML.type ButtonProps = {
variant?: "primary" | "secondary";
};
function Button({ variant = "primary" }: ButtonProps) {
// TypeScript restringe variant a "primary" | "secondary" (não undefined)
}? no tipo.children?: React.ReactNode ao seu tipo.children dos leitores da definição do tipo.children: React.ReactNode explícito no tipo para clareza.React.FC não inclui mais children implicitamente.children implícita.children, declare-o explicitamente em seu tipo de props.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 aceita tags de string ("div", "span") e tipos de componentes.Revisado por Chris St. John·Última atualização: 7 de jul. de 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥