React com TypeScript e Biome
Este documento define as boas práticas de desenvolvimento em React com TypeScript, aplicadas ao frontend da Smart NX (SNX).
O foco é garantir previsibilidade, segurança de tipos e código padronizado, com validação automática via Biome.
Este guia complementa o documento de Validação de Commits (Husky) e o de Padrões de Código.
1. Princípios Gerais
- Tipagem forte sempre.
Nenhum código deve depender de inferências ambíguas do TypeScript — prefira declarar tipos explicitamente. - Evite o uso desnecessário de
any.
Sempre que possível, utilize tipos genéricos,unknownounever. - Exceções são permitidas, mas justificadas.
Todo uso deany,@ts-ignoreouas unknowndeve ser documentado com comentário explicativo. - Código deve ser previsível.
Evite mutações e side effects fora de hooks específicos (useEffect,useLayoutEffect). - Linting obrigatório.
O Biome é o validador padrão e nenhum commit é aceito sem passar por ele.
2. Tipagem Correta no Dia a Dia
2.1. O uso incorreto de any
Evite:
function handleResponse(data: any) {
setUser(data);
}
Prefira:
function handleResponse(data: IUserResponse) {
setUser(data);
}
Exceção justificada:
// Exceção: tipagem genérica da lib externa não cobre este caso
function handleEvent(event: any) {
trackUnknownEvent(event);
}
Sempre descreva o motivo em comentário e apenas onde não há alternativa segura.
2.2. Uso correto de unknown e never
// `unknown` → valor que precisa ser refinado
function parseInput(value: unknown) {
if (typeof value === "string") return value.toUpperCase();
throw new Error("Valor inválido");
}
// `never` → função que nunca retorna
function throwError(message: string): never {
throw new Error(message);
}
2.3. Tipagem de Hooks e Estados
const [user, setUser] = useState<IUser | null>(null);
const [loading, setLoading] = useState<boolean>(false);
Nunca use
useState()vazio. Sempre inicialize com tipo explícito, mesmo que o valor inicial sejanull.
2.4. Tipagem de Eventos React
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
};
Evite event: any ou event: unknown para eventos React — use sempre os tipos do próprio pacote.
3. Uso Correto de Generics
3.1. Com hooks personalizados
function useFetch<T>(url: string) {
const [data, setData] = useState<T | null>(null);
useEffect(() => {
fetch(url)
.then((res) => res.json())
.then(setData);
}, [url]);
return data;
}
O uso de generics (
<T>) permite reuso tipado do hook em diferentes contextos.
4. Padrões Recomendados com Biome
O Biome valida automaticamente estilo, imports, e boas práticas.
4.1. Importação e ordem
Correto:
import React, { useState, useEffect } from "react";
import { Button } from "@design-system/Button";
import * as S from "./style";
Incorreto:
import * as S from "./style";
import { Button } from "@design-system/Button";
import React from "react";
O Biome valida automaticamente a ordem de imports. Sempre importe React → libs → módulos internos → estilos.
4.2. Constantes e funções puras
Correto:
const formatCurrency = (value: number): string =>
new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(value);
Evite:
function formatCurrency(value) {
return "R$ " + value;
}
4.3. Nomeação de componentes
Correto:
export const UserCard: React.FC<IUserCardProps> = ({ user }) => (
<S.Container>{user.name}</S.Container>
);
Evite:
export default function userCard(props) {
return <div>{props.user.name}</div>;
}
Evite
default export. Prefiraexport const, pois facilita tree-shaking e refatoração.
5. Exceções Controladas
Há casos em que regras podem ser quebradas, mas devem ser documentadas e justificadas.
5.1. Uso justificado de any
// Exceção: biblioteca não fornece tipos adequados
// TODO: substituir por tipo customizado quando disponível
const result: any = thirdPartyLib.runUnsafe();
5.2. @ts-ignore
// @ts-ignore - tipagem incorreta na lib react-chartjs-2
<Chart data={unsafeData} />;
5.3. as unknown as
// Conversão entre tipos incompatíveis apenas por limitação temporária
const config = rawConfig as unknown as SafeConfig;
Sempre inclua o porquê da exceção e, se possível, um TODO com plano de correção.
6. Regras de Biome no Contexto SNX
| Categoria | Regra | Ação |
|---|---|---|
| Imports | Ordem e agrupamento padronizados | error |
Uso de var | Proibido | error |
| Declaração de função anônima | Deve usar arrow functions | warn |
Uso de any | Permitido apenas com comentário explicativo | warn |
| Campos não utilizados | Bloqueia build (noUnusedVars) | error |
Uso de console.log | Proibido em PRs | error |
7. Boas Práticas de Legibilidade
- Evite lógica inline dentro do JSX. Extraia para funções auxiliares nomeadas.
- Agrupe hooks por função (estado, callbacks, efeitos).
- Nunca misture dados e renderização em um único hook.
- Prefira early return a blocos
if/elseaninhados. - Evite props booleanas invertidas (ex:
!isHidden→ prefiraisVisible).
8. Dicas Avançadas
8.1. Uso de useMemo e useCallback
const filteredData = useMemo(
() => data.filter((item) => item.active),
[data]
);
Evite memorização prematura — use apenas em cálculos custosos ou listas grandes.
8.2. Evite renderizações desnecessárias
Use React.memo em componentes puros que recebem apenas props estáveis:
export const Header = React.memo(({ title }: { title: string }) => (
<S.Container>{title}</S.Container>
));
8.3. Uso do strict mode
Sempre mantenha o app React em Strict Mode, mesmo em desenvolvimento — o Biome ajuda a detectar efeitos duplicados ou não idempotentes.
Histórico de Versões
| Data | Versão | Autor / Revisor | Alterações |
|---|---|---|---|
| 08/04/2026 | v1.1.0 | Juathan Coelho Duarte | Padronização de prefixos I/T nos exemplos de tipagem |
| 29/10/2025 | v1.0.0 | @Matheus Telles | Criação inicial e estrutura base do documento |