O tratamento de erros para operações assíncronas é frequentemente escrito com try-catch, mas o local onde as exceções ocorrem e o local onde são tratadas tendem a divergir. Com o padrão do tipo Result, você pode separar explicitamente sucesso e falha como valores de retorno.
Pré-requisito: Conversão para o Tipo Error
Um helper para converter de forma confiável erros do tipo unknown para o tipo Error.
export function toError(error: unknown): Error { if (error instanceof Error) return error; return new Error(error as never);}Definição do Tipo Result
interface Failure { data: undefined; error: Error;}
interface Success<T> { data: T; error: undefined;}
type Result<T> = Success<T> | Failure;Exemplo de Implementação do Wrapper fetch
import { toError } from './toError.js'
export async function fetcher<T>( url: RequestInfo, init?: RequestInit): Promise<Result<T>> { const UNDEF = undefined;
// Quando fetch falha (erros de rede, etc.) const response = await fetch(url, init).catch(toError); if (response instanceof Error) { return { data: UNDEF, error: response }; }
// Respostas de erro HTTP if (!response.ok) { return { data: UNDEF, error: new Error(`HTTP ${response.status}: ${response.statusText}`) }; }
// Sucesso const data = await response.json(); return { data, error: UNDEF };}Exemplo de Uso
const result = await fetcher<User>("/api/user/123");
if (result.error) { console.error("Falha ao buscar:", result.error.message); return;}
// Quando result.error é undefined, TypeScript infere result.data como Tconsole.log(result.data.name);Benefícios e Considerações
Benefícios:
- Sucesso e falha ficam claros pelo tipo de retorno
- Menos blocos try-catch melhoram a legibilidade
- O tratamento de erros pode ser forçado (omissão causa erros de tipo)
Considerações:
- Se a proposta ECMAScript Safe Assignment Operator for padronizada, funcionalidade similar integrada pode se tornar disponível
- Não é tão completo quanto os tipos Result embutidos na linguagem de Go ou Rust
- Tratamento detalhado de erros como erros de validação requer implementação separada
A implementação é simples, mas é eficaz quando você deseja tratar erros de forma type-safe em projetos de pequena escala.
hsb.horse