Skip to main content

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​

  1. Tipagem forte sempre.
    Nenhum código deve depender de inferências ambíguas do TypeScript — prefira declarar tipos explicitamente.
  2. Evite o uso desnecessário de any.
    Sempre que possível, utilize tipos genéricos, unknown ou never.
  3. Exceções são permitidas, mas justificadas.
    Todo uso de any, @ts-ignore ou as unknown deve ser documentado com comentário explicativo.
  4. Código deve ser previsível.
    Evite mutações e side effects fora de hooks específicos (useEffect, useLayoutEffect).
  5. 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 seja null.


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. Prefira export 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​

CategoriaRegraAção
ImportsOrdem e agrupamento padronizadoserror
Uso de varProibidoerror
Declaração de função anônimaDeve usar arrow functionswarn
Uso de anyPermitido apenas com comentário explicativowarn
Campos não utilizadosBloqueia build (noUnusedVars)error
Uso de console.logProibido em PRserror

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/else aninhados.
  • Evite props booleanas invertidas (ex: !isHidden → prefira isVisible).

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​

DataVersãoAutor / RevisorAlterações
08/04/2026v1.1.0Juathan Coelho DuartePadronização de prefixos I/T nos exemplos de tipagem
29/10/2025v1.0.0@Matheus TellesCriação inicial e estrutura base do documento