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
});