TypeScript: Padrões em React que Escalam em Produção
Neste artigo
TypeScript não é sobre encher o código de tipos até o compilador parar de reclamar. Em projetos React de médio e grande porte, o objetivo é evitar bugs e deixar claro o que cada parte do sistema espera receber.
Depois de anos com React em produção (AEM, LGPD, produtos próprios), estes são os padrões que mais ajudam quando o time cresce.
1. Modele o domínio antes do componente
Em vez de data: any, defina tipos perto do hook ou do service:
tsexport type PricePoint = {
date: string
value: number
marketplace: 'amazon' | 'mercadolivre' | 'shopee'
}
export type ProductSummary = {
id: string
title: string
currentPrice: number
history: PricePoint[]
}
O componente recebe ProductSummary — não um JSON solto da API. Se o backend mudar, o erro aparece no lugar certo.
2. Use unions para estados de UI
Loading, erro, vazio e sucesso ficam mais seguros com um tipo que discrimina o estado:
tstype AsyncState<T> =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'error'; message: string }
| { status: 'success'; data: T }
No JSX, um switch com never no default força tratar todos os casos — e evita mostrar data enquanto ainda está carregando.
3. Props claras, sem vários booleans
Prefira uma variante nomeada a cinco flags true/false:
ts// ❌ difícil de manter
type ButtonProps = { primary?: boolean; danger?: boolean; ghost?: boolean }
// ✅ claro e extensível
type ButtonProps = {
variant?: 'primary' | 'secondary' | 'ghost' | 'danger'
size?: 'sm' | 'md' | 'lg'
}
Em design systems, isso evita combinações inválidas (primary + ghost ao mesmo tempo).
4. satisfies e as const para configs
Menus, rotas e feature flags ficam tipados sem perder os valores literais:
tsconst NAV_ITEMS = [
{ href: 'expertise', key: 'expertise' },
{ href: 'projects', key: 'projects' },
] as const satisfies ReadonlyArray<{ href: string; key: string }>
Você mantém autocomplete e validação na definição.
5. Validação na borda da API (Zod ou similar)
TypeScript some depois do build. Validação em runtime na entrada da API protege a UI:
tsconst ProductSchema = z.object({
id: z.string(),
title: z.string(),
currentPrice: z.number().nonnegative(),
})
const product = ProductSchema.parse(await response.json())
Use especialmente com APIs de terceiros ou scraping, onde o payload pode mudar sem aviso.
Conclusão
TypeScript escala quando os tipos descrevem o contrato entre camadas — não quando são decoração no JSX.
Comece pelo domínio, modele estados assíncronos com unions, simplifique props e valide na entrada. O time ganha velocidade com mais confiança no deploy.




Comentários
Faça login com sua conta GitHub para comentar. Os comentários ficam públicos nas Discussions do repositório de comentários do blog.