Skip to content
tutorials

A atualização do Effect que torna as falhas visíveis

Um `Promise<User>` limpo pode ocultar as falhas que derrubam serviços em produção. A parte surpreendente: adicionar segurança pode tornar seus tipos mais informativos — não mais complicados.

Marcus Lee
A atualização do Effect que torna as falhas visíveis

O tipo Promise tem um ponto cego em produção

Imagine um contrato comum em sua base de código: Promise<User>. Este tipo descreve perfeitamente o caminho feliz — você espera um objeto User se tudo correr bem. Mas e quanto ao mundo real? Ele não diz nada sobre um erro HTTP, um usuário inexistente ou uma requisição que trava indefinidamente, deixando sua aplicação esperando.

O TypeScript, infelizmente, não tipa de forma confiável as rejeições de promessas. Seus manipuladores catch frequentemente recebem um valor unknown, forçando você a adivinhar em tempo de execução o que deu errado. Isso significa que as equipes gastam um tempo valioso estabelecendo comportamentos de falha por tentativa e erro, e não por verificações robustas do compilador.

Considere um serviço que busca perfis de usuário. Quem chama precisa de mais do que apenas um User ou um erro sem tipo. Eles precisam saber se devem tentar a requisição novamente de forma automática (como em uma falha de rede transitória), exibir uma mensagem clara de "usuário não encontrado" ou parar de esperar após um tempo limite específico. Sem essa clareza em seus tipos, seu ambiente de produção se torna um ponto cego, escondendo informações cruciais sobre por que as coisas falham.

O Effect adiciona as partes que faltam ao contrato

O Effect altera o contrato de Promise<User> para algo mais robusto. Sua assinatura principal é Effect<A, E, R>, que descreve precisamente três aspectos cruciais de qualquer computação: o valor de sucesso, a falha tipada e quaisquer dependências necessárias.

Vamos detalhar isso. A representa o valor que você obtém no sucesso, como User em nosso exemplo. E é onde a mágica acontece para as falhas, fornecendo uma união tipada de todos os erros esperados, como HttpError | NotFound. Finalmente, R significa "requisitos" — os serviços ou dependências que o código precisa para rodar, como um cliente HTTP ou uma conexão com banco de dados.

Considere nossa função de busca de usuário do vídeo. Em vez de apenas Promise<User>, seu tipo Effect pode ser Effect<User, HttpError | NotFound, SomeHttpClient>. Isso torna o contrato explícito: ele diz a você não apenas que você pode obter um User, mas também que um HttpError ou uma condição NotFound são modos de falha específicos e esperados.

Esta é uma grande diferença em relação a uma promise comum. Computações Effect são valores lazy, o que significa que eles descrevem o que fazer, mas não quando fazer. Você compõe toda a sua computação, incluindo tentativas, timeouts e políticas de tratamento de erro, antes da execução. Isso mantém todos os requisitos e resultados potenciais visíveis enquanto você constrói seu programa, transformando um ponto cego em um mapa detalhado.

Veja o tipo de erro mudar conforme você adiciona segurança

Vamos rastrear como o tipo de erro evolui à medida que adicionamos resiliência a um pipeline de busca de dados. Inicialmente, nosso Effect<User, HttpError | NotFound, R> pode falhar com um HttpError ou um erro NotFound.

Primeiro, aplicamos uma política de repetição exponencial para lidar com HttpErrors transitórios, mas isso não altera a assinatura do tipo porque as repetições não eliminam a possibilidade de um HttpError. Em seguida, adicionamos um timeout de dois segundos. Isso introduz imediatamente TimeoutError em nosso tipo de erro, tornando-o Effect<User, HttpError | NotFound | TimeoutError, R>.

Então, tratamos explicitamente o caso NotFound fornecendo um valor de fallback. Como mágica, o tipo NotFound desaparece da nossa assinatura de erro porque agora é garantido que ele será tratado. Nosso tipo se torna Effect<User, HttpError | TimeoutError, R>. Isso não é apenas um truque inteligente; é o compilador fazendo uma contabilidade em tempo real de falhas potenciais.

Para provar isso, reduzimos o timeout para apenas 50 milissegundos. Executar o código então produz um TimeoutError, exatamente como o sistema de tipos previu. Esse ciclo de feedback em tempo de compilação, verificado em tempo de execução, é um recurso poderoso do Effect: Production-Grade TypeScript e sua abordagem para tornar falhas visíveis e gerenciáveis.

Gostando do artigo? Receba um assim na sua caixa de entrada toda manhã.

um e-mail por dia · cancele em dois cliques · sem rastreadores de terceiros

A Recompensa — e o Custo da Mudança

O rastreamento explícito de erros e dependências brilha em serviços críticos como autenticação e pagamentos. Nesses domínios, caminhos de rejeição ocultos — como o timeout de uma API externa ou a queda de uma conexão com o banco de dados — tornam a recuperação e a revisão muito mais difíceis. A abordagem orientada a tipos do Effect garante que você trate esses modos de falha potenciais de forma proativa, não reativa.

O Effect oferece mais do que um tipo Result básico. Ele inclui um runtime robusto que fornece ferramentas para retries, timeouts, concorrência e gerenciamento de dependências nativamente. Em vez de substituir seu código baseado em Promise existente instantaneamente, o Effect pode complementá-lo, permitindo a adoção gradual e a integração em partes específicas e de alto valor da sua aplicação.

Adotar o Effect requer um investimento em aprendizado. O modelo, com sua assinatura distinta Effect<A, E, R>, leva tempo para ser compreendido, especialmente como os tipos de erro evoluem através do seu pipeline. Como os tipos do Effect se propagam naturalmente através das fronteiras da aplicação, as equipes devem pesar cuidadosamente esses custos de aprendizado e migração contra os benefícios de maior confiabilidade e observabilidade, particularmente para sistemas sensíveis.

Perguntas Frequentes

O que é o Effect no TypeScript?

Effect é uma biblioteca para modelar programas assíncronos com valores de sucesso explícitos, erros tipados e serviços necessários.

Como o Effect é diferente de uma Promise?

Uma Promise descreve um valor que pode ser resolvido ou rejeitado, mas não codifica tipos de rejeição. O Effect também modela falhas tipadas e dependências.

Como os tipos do Effect mudam quando um erro é tratado?

Tratar um erro tipado remove essa falha do tipo de erro do Effect; adicionar uma operação como um timeout pode adicionar uma nova falha tipada.

Todo projeto TypeScript deveria adotar o Effect?

Não necessariamente. Ele pode ajudar sistemas complexos que precisam de falhas explícitas e controles de tempo de execução, mas seus conceitos e pegada de tipos exigem um investimento de adoção.

Found this useful? Share it.

For builders

Want Stork to write one of these about your product?

Send us a URL. We use the product, form a view, and publish what we actually think — in 8 languages, labeled Sponsored, with no copy approval on your side. That last part is what makes it worth quoting.

See how it works$199 · AI tools & software only

Para builders

Esta página está trabalhando para a ferramenta de outra pessoa.

Agentes de IA leem. Compradores chegam nela. Ela responde em oito idiomas e via MCP. Sua ferramenta pode ter uma assim — no ar em 24 horas.