Pular para o conteúdo
TypeScript

TypeScript para React: Guia Prático 2026

Domine TypeScript em projetos React com exemplos práticos. Tipagem de props, hooks, eventos, API responses, generics e patterns que devs seniores usam.

Gustavo Miranda
18 min de leitura
LinkedIn𝕏X
TypeScriptReactFrontendTiposPatterns

Por que isso é importante

TypeScript para React: Guia Prático 2026. Domine TypeScript em projetos React com exemplos práticos. Tipagem de props, hooks, eventos, API responses, generics e patterns que devs seniores usam.

TypeScript em 5 Minutos

TypeScript é JavaScript com tipos. Todo código JavaScript válido já é TypeScript válido. Você adiciona tipos gradualmente: comece com props de componentes, depois hooks, depois API responses. Não precisa tipar tudo no dia 1.

Setup rápido

npx create-next-app@latest --typescript já configura tudo. Para projetos existentes: npm install -D typescript @types/react @types/node e renomeie .jsx para .tsx. O compilador infere tipos automaticamente na maioria dos casos.

Tipando Props de Componentes

Props são o contrato entre componentes. TypeScript garante que quem usa o componente passa os dados corretos. Erros aparecem no editor, não em produção.

1
Interface para props: Defina interface ButtonProps { label: string; onClick: () => void; disabled?: boolean; }. O ? marca props opcionais.
2
Children tipado: Use children: React.ReactNode para aceitar qualquer JSX. React.ReactElement se quiser apenas elementos React (sem strings).
3
Union types para variantes: variant: "primary" | "secondary" | "ghost". O editor mostra as opções válidas no autocompletar. Erro se passar valor inválido.
4
Estendendo HTML nativo: interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>. Herda todas as props de um button HTML (onClick, disabled, type, etc.) e adiciona as suas.

Interface vs Type

Use interface para props de componentes (extensível, mergeável). Use type para unions, intersections e tipos computados. Na prática, ambos funcionam em 95% dos casos. A convenção React é interface para props.

Tipando Hooks

useState

TypeScript infere o tipo do valor inicial. useState(0) é automaticamente number. Para tipos complexos ou inicialização com null, declare explicitamente: useState<User | null>(null).

1
Tipo inferido: const [count, setCount] = useState(0) — TypeScript sabe que count é number e setCount aceita number.
2
Tipo explícito: const [user, setUser] = useState<User | null>(null) — necessário quando o tipo muda (null → User após fetch).
3
Arrays: const [items, setItems] = useState<Product[]>([]) — array vazio não infere o tipo dos elementos, declare explicitamente.

useRef

Para refs DOM: useRef<HTMLInputElement>(null). O tipo garante que ref.current tem as propriedades corretas (value, focus, etc.). Para valores mutáveis: useRef<number>(0).

useReducer

Discriminated unions brilham aqui. Defina cada action como tipo separado: type Action = { type: "increment" } | { type: "set"; payload: number }. O TypeScript garante que payload só existe quando type === "set". Switch no reducer tem autocomplete e exaustividade.

Tipando Eventos

Eventos no React têm tipos específicos. O padrão: React.[Evento]Event<HTMLElemento>.

1
Click: React.MouseEvent<HTMLButtonElement>. Acesse e.currentTarget para o elemento que disparou.
2
Input change: React.ChangeEvent<HTMLInputElement>. O e.target.value é tipado como string automaticamente.
3
Form submit: React.FormEvent<HTMLFormElement>. Chame e.preventDefault() e extraia dados com FormData.
4
Keyboard: React.KeyboardEvent<HTMLInputElement>. Use e.key === "Enter" para detectar teclas específicas.

Tipando API Responses

Dados de API são o ponto mais vulnerável. Sem tipos, um campo renomeado no backend quebra o frontend silenciosamente. Com TypeScript + Zod, a validação acontece em runtime e compilação.

1
Interface para response: Defina interface User { id: string; name: string; email: string; }. Aplique no fetch: const data: User[] = await res.json().
2
Zod para validação runtime: Defina schema Zod e infira o tipo: type User = z.infer<typeof userSchema>. Um único source of truth para tipo e validação.
3
Generics para fetch: Crie async function fetchApi<T>(url: string): Promise<T>. Reutilize em qualquer endpoint com tipo específico.
4
Error handling tipado: Defina type ApiResponse<T> = { success: true; data: T } | { success: false; error: string }. O TypeScript força check de success antes de acessar data.

Generics: O Superpoder do TypeScript

Generics criam componentes e funções que funcionam com qualquer tipo mantendo type safety. É como um parâmetro, mas para tipos em vez de valores.

1
Componente genérico de lista: function List<T>({ items, renderItem }: { items: T[]; renderItem: (item: T) => ReactNode }). Funciona com User[], Product[], qualquer tipo. O caller define T implicitamente.
2
Hook genérico: function useFetch<T>(url: string): { data: T | null; loading: boolean; error: string | null }. O tipo retornado acompanha o genérico.
3
Constraints: <T extends { id: string }> garante que T tem propriedade id. Restringe o genérico sem perder flexibilidade.

Utility Types Essenciais

TypeScript inclui tipos utilitários que transformam tipos existentes. Evitam duplicação e mantêm tipos sincronizados.

1
Partial<T>: Torna todas as propriedades opcionais. Ideal para updates: function updateUser(id: string, data: Partial<User>). Permite enviar apenas os campos que mudaram.
2
Pick<T, K>: Seleciona propriedades específicas. Pick<User, "name" | "email"> cria tipo com apenas name e email. Ideal para formulários parciais.
3
Omit<T, K>: Remove propriedades. Omit<User, "id" | "createdAt"> para formulários de criação que não precisam de id.
4
Record<K, V>: Cria objeto tipado. Record<string, number> para dicionários. Record<Status, Color> para mapas de configuração.
5
ReturnType<T>: Extrai o tipo de retorno de uma função. ReturnType<typeof getUser> mantém tipos sincronizados com a implementação sem duplicar.

Patterns Avançados para React

1
Discriminated union props: type Props = { variant: "link"; href: string } | { variant: "button"; onClick: () => void }. Props mudam baseado no variant. TypeScript garante que href só existe quando variant é "link".
2
Polymorphic components: Componente que aceita as prop para mudar o elemento renderizado. Button que pode ser <a> ou <button> com tipos corretos para cada um.
3
Strict context: Crie createStrictContext<T>() que retorna erro se usado fora do Provider ao invés de retornar undefined. Elimina null checks em consumers.
4
Type-safe routing: Com Next.js App Router, defina tipos para params e searchParams. { params: { slug: string } } garante que a página recebe o parâmetro esperado.

TypeScript com Next.js

Next.js tem suporte first-class para TypeScript. Tipos para pages, layouts, API routes e metadata são gerados automaticamente.

Tipos Next.js essenciais

Metadata: import type { Metadata } from "next" para tipar metadata estática.
Route params: { params: Promise<{ slug: string }> } no Next.js 15+ (params é async).
Server Actions: Tipo do FormData e retorno são inferidos. Use Zod para validar inputs.
API Routes: NextRequest e NextResponse do next/server.

Checklist TypeScript + React

Props de componentes tipadas com interface
useState com tipo explícito quando valor inicial é null ou array vazio
useRef com tipo do elemento DOM correto
Eventos tipados: MouseEvent, ChangeEvent, FormEvent
API responses validadas com Zod + z.infer
Generics em componentes e hooks reutilizáveis
Utility types (Partial, Pick, Omit) para derivar tipos
Discriminated unions para props condicionais
Strict mode habilitado no tsconfig.json
Nunca usar any — prefira unknown + type guard

Conclusão

TypeScript não é overhead — é investimento. O tempo gasto tipando é recuperado 10x em bugs prevenidos, refactors seguros e onboarding rápido de novos devs. Comece tipando props e API responses. Em 2 semanas, você não imagina voltar para JavaScript puro.

Aprenda TypeScript na Prática

TypeScript é parte central do bootcamp CrazyStack. Aprenda com projetos reais em React e Next.js.