Skip to content

Uso Básico

Requisição GET Simples

typescript
import { typedFetch, NotFoundError, UnauthorizedError } from '@pbpeterson/typed-fetch';

interface User {
  id: number;
  name: string;
  email: string;
}

// Especifique erros esperados para melhor segurança de tipos
type ExpectedErrors = NotFoundError | UnauthorizedError;
const { response, error } = await typedFetch<User[], ExpectedErrors>('/api/users');

if (error) {
  if (error instanceof NotFoundError) {
    console.log('Endpoint de usuários não encontrado');
  } else if (error instanceof UnauthorizedError) {
    console.log('Autenticação necessária');
  } else {
    console.error('Erro inesperado:', error.statusText);
  }
} else {
  const users = await response.json(); // Tipo: User[]
  console.log('Usuários:', users);
}

Especificando Erros de Cliente Esperados

⚠️ IMPORTANTE: É altamente recomendado especificar quais erros de cliente (4xx) você espera da sua API. Quando você não especifica o segundo parâmetro genérico, a biblioteca incluirá TODOS os possíveis erros de cliente no tipo union de erro, tornando o tratamento de erros mais complexo.

typescript
import { typedFetch, NotFoundError, UnauthorizedError } from '@pbpeterson/typed-fetch';

// ❌ Sem especificar erros esperados - inclui TODOS os erros de cliente
const { response, error } = await typedFetch<User[]>('/api/users');
// tipo do error: BadRequestError | PaymentRequiredError | UnauthorizedError | ... (30+ tipos de erro) | ServerErrors | NetworkError | null

// ✅ Especificando apenas os erros de cliente esperados - muito mais limpo
type ExpectedErrors = NotFoundError | UnauthorizedError;
const { response: betterResponse, error: betterError } = await typedFetch<User[], ExpectedErrors>('/api/users');
// tipo do betterError: NotFoundError | UnauthorizedError | ServerErrors | NetworkError | null

if (betterError) {
  if (betterError instanceof NotFoundError) {
    console.log('Usuários não encontrados');
  } else if (betterError instanceof UnauthorizedError) {
    console.log('Por favor, faça autenticação');
  } else {
    // Erros de servidor (5xx) ou erros de rede - geralmente inesperados
    console.error('Erro inesperado:', betterError.statusText);
  }
}

Por que sempre incluímos Erros de Servidor e Erros de Rede:

  • Erros de Servidor (5xx): São inesperados e não podem ser controlados pelo cliente
  • Erros de Rede: Problemas de conexão, timeouts e falhas de DNS são sempre possíveis
  • Esses tipos de erro ajudam você a lidar com situações inesperadas de forma elegante

Requisição POST com Body

typescript
import { typedFetch, BadRequestError } from '@pbpeterson/typed-fetch';

const newUser = { name: 'John Doe', email: 'john@example.com' };

// Especifique BadRequestError como erro de cliente esperado para validação POST
const { response, error } = await typedFetch<User, BadRequestError>('/api/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(newUser),
});

if (error) {
  if (error instanceof BadRequestError) {
    const validationErrors = await error.json();
    console.error('Validação falhou:', validationErrors);
  } else {
    console.error('Requisição falhou:', error.statusText);
  }
} else {
  const user = await response.json(); // Tipo: User
  console.log('Usuário criado:', user);
}

Clonagem de Resposta de Erro

Manipule respostas de erro que precisam ser lidas múltiplas vezes:

typescript
import { typedFetch, UnauthorizedError, NotFoundError } from '@pbpeterson/typed-fetch';

type ExpectedErrors = UnauthorizedError | NotFoundError;
const { error } = await typedFetch<User[], ExpectedErrors>('/api/users');

if (error && 'clone' in error) {
  // Clone o erro para ler o corpo da resposta múltiplas vezes
  const clonedError = error.clone();
  
  if (error instanceof UnauthorizedError) {
    console.log('Autenticação necessária');
  } else if (error instanceof NotFoundError) {
    console.log('Usuários não encontrados');
  }
  
  // Logar os detalhes do erro
  const errorDetails = await error.json();
  console.error('Detalhes do erro:', errorDetails);
  
  // Enviar para serviço de monitoramento
  const monitoringData = await clonedError.json();
  analytics.track('api_error', monitoringData);
}

Cancelamento e Timeout de Requisição

Como typedFetch usa a mesma API do fetch nativo, todos os recursos modernos funcionam:

typescript
import { typedFetch, UnauthorizedError, NotFoundError } from '@pbpeterson/typed-fetch';

// Cancelamento de requisição
const controller = new AbortController();

type ExpectedErrors = UnauthorizedError | NotFoundError;
const { response, error } = await typedFetch<User[], ExpectedErrors>('/api/users', {
  signal: controller.signal
});

// Cancelar após 2 segundos
setTimeout(() => controller.abort(), 2000);

// Timeout de requisição (navegadores modernos)
const { response: timeoutResponse, error: timeoutError } = await typedFetch<User[], ExpectedErrors>('/api/users', {
  signal: AbortSignal.timeout(5000) // timeout de 5 segundos
});

Lançado sob a Licença MIT.