Feature flags em TypeScript: como ativar funcionalidades sem deploy

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Quando o deploy é uma dor: por que os desenvolvedores amam feature flags

\n\n

Imagine: você passou uma semana desenvolvendo uma nova funcionalidade. Cobriu com testes, passou pelo code review, apertou o botão de deploy. E então — bum! — tudo quebra em produção. Usuários furiosos, gerente nervoso, você correndo para reverter a versão. Familiar?

\n\n

Agora imagine outro cenário: você ativa a nova funcionalidade apenas para 5% dos usuários. Observa as métricas. Vê que está tudo bem. Aumenta gradualmente a porcentagem para 100%. Sem estresse, sem reversões, apenas confiança tranquila.

\n\n

Essa é a mágica dos feature flags (também conhecidos como feature toggles, flags de funcionalidade). Em projetos TypeScript, essa técnica é especialmente boa graças à tipagem estática e ao controle rigoroso de tipos. Hoje vamos entender como implementar feature flags no seu projeto para que você durma tranquilo e as funcionalidades sejam ativadas sem dor.

\n\n

O que são feature flags em palavras simples

\n\n

Feature flag é um interruptor condicional no código que permite ativar ou desativar uma funcionalidade sem alterar o código e sem um novo deploy. Funciona mais ou menos assim:

\n\n
if (featureFlags.isEnabled('new-checkout')) {\n  // novo código\n} else {\n  // código antigo\n}\n
\n\n

Tudo que é genial é simples, certo? Mas por trás dessa simplicidade está uma ferramenta poderosa usada por Google, Netflix, Facebook e outros gigantes. Eles não fazem deploy de cada detalhe — eles gerenciam o comportamento da aplicação através de um painel de controle centralizado.

\n\n

Quando feature flags são realmente necessárias

\n\n
    \n
  • Canary release — lançamento de uma nova funcionalidade para uma pequena parte dos usuários
  • \n
  • Dark launch — teste oculto, onde a funcionalidade existe mas os usuários não a veem
  • \n
  • Teste A/B — comparação de duas versões de uma funcionalidade
  • \n
  • Kill switch — desativação de emergência de código problemático sem deploy
  • \n
  • Teste de permissão — teste em usuários internos ou por funções
  • \n
\n\n

Em projetos TypeScript, os feature flags ganham um charme especial: o compilador verifica se você está usando as flags corretamente, não confunde tipos e não esquece de tratar todos os estados.

\n\n

Arquitetura do sistema de feature flags

\n\n

Antes de escrever código, vamos entender do que consiste um sistema bem projetado de gerenciamento de funcionalidades.

\n\n

Componentes básicos

\n\n
    \n
  1. Armazenamento de flags — onde os valores ficam (JSON, banco de dados, serviço externo)
  2. \n
  3. Provedor — módulo que carrega e armazena em cache as flags
  4. \n
  5. Parte cliente — código que verifica o estado das flags
  6. \n
  7. Painel de controle — interface para alterar as flags em tempo real
  8. \n
\n\n

Implementação mais simples em TypeScript

\n\n

Vamos começar com o exemplo mais básico. Criaremos um tipo para as flags e um serviço simples:

\n\n
// types/feature-flags.ts\nexport type FeatureFlag = \n  | 'new-checkout'\n  | 'dark-mode'\n  | 'recommendations-v2'\n  | 'beta-chat';\n\nexport interface FeatureFlagConfig {\n  flag: FeatureFlag;\n  enabled: boolean;\n  rolloutPercentage?: number;\n  userIds?: string[];\n}\n
\n\n

Agora escrevemos o serviço em si:

\n\n
// services/feature-flag.service.ts\nexport class FeatureFlagService {\n  private flags: Map<FeatureFlag, FeatureFlagConfig> = new Map();\n\n  constructor(initialFlags: FeatureFlagConfig[]) {\n    initialFlags.forEach(flag => {\n      this.flags.set(flag.flag, flag);\n    });\n  }\n\n  isEnabled(flag: FeatureFlag, userId?: string): boolean {\n    const config = this.flags.get(flag);\n    if (!config) return false;\n\n    if (!config.enabled) return false;\n\n    // Verificação por usuários específicos\n    if (config.userIds && userId) {\n      return config.userIds.includes(userId);\n    }\n\n    // Rollout por porcentagem                

Blogs

Book Recommendations