Introdução: por que o Angular grita "Can't resolve all parameters"?
Você está escrevendo seu primeiro componente Angular, orgulhosamente adiciona no construtor um serviço para trabalhar com API, executa a aplicação — e imediatamente recebe no console uma mensagem vermelha:
EXCEPTION: Can't resolve all parameters for MyComponent: (?).Familiar? Esse erro é uma verdadeira pedra no caminho para iniciantes e até mesmo para desenvolvedores experientes que estão migrando do AngularJS. Ele ocorre quando o Angular não consegue entender qual serviço deve ser injetado no componente. Neste artigo, analisaremos todas as causas do erro Can't resolve all parameters for component, mostraremos exemplos práticos em TypeScript e daremos soluções passo a passo. Você não apenas corrigirá o bug, mas também entenderá como funciona a Dependency Injection (DI) no Angular.
O que é Dependency Injection e por que é importante?
O Angular é construído sobre o sistema de injeção de dependências (DI). Quando você escreve:
constructor(private myService: MyService) {}O Angular cria automaticamente uma instância de MyService e a passa para o componente. Mas para isso, ele precisa saber três coisas:
- Qual tipo (classe) deve ser injetado.
- Onde o provider para esse tipo está registrado.
- O que fazer se o provider não existir.
Se pelo menos um desses pontos não for atendido, você receberá o erro "Can't resolve all parameters".
Principais causas do erro
Selecionamos os 5 cenários mais comuns que levam a esse erro. Cada um será analisado com código.
1. Serviço não registrado nos providers
A causa mais óbvia. Você criou o serviço, mas esqueceu de adicioná-lo em providers do módulo ou componente.
Exemplo de código com erro:
// my.service.ts@Injectable()export class MyService { getData() { return 'data'; }}
// my.component.ts@Component({ selector: 'app-my', template: '...' })export class MyComponent { constructor(private myService: MyService) {} // Erro!}Solução: Registre o serviço no módulo:
@NgModule({ providers: [MyService] // <-- obrigatório})export class AppModule { }Ou no próprio componente (se o serviço for necessário apenas para ele):
@Component({ providers: [MyService]})export class MyComponent { ... }2. Ausência do decorador @Injectable()
Mesmo que você tenha registrado o serviço nos providers, se esquecer de adicionar o decorador @Injectable() — o Angular não conseguirá ler os metadados.
Exemplo:
// Sem decoradorexport class MyService { ... }
// No componenteconstructor(private myService: MyService) {} // Erro!Solução: Sempre adicione @Injectable():
@Injectable({ providedIn: 'root' }) // ou apenas @Injectable()export class MyService { ... }A propósito, providedIn: 'root' registra automaticamente o serviço no nível do injetor raiz — esta é a abordagem moderna e recomendada.
3. Conflito com compilação AOT e parâmetros do construtor
O Angular usa dois modos de compilação: JIT (Just-in-Time) e AOT (Ahead-of-Time). O erro Can't resolve all parameters ocorre frequentemente com AOT, se o TypeScript não preservou as informações sobre os tipos dos parâmetros.
Causa: Em versões antigas do Angular (anteriores à 5) ou ao usar certas configurações do tsconfig, o TypeScript podia remover os metadados dos tipos. Por exemplo, se você usasse emitDecoratorMetadata: false ou esquecesse de importar reflect-metadata.
Solução:
- Certifique-se de que no
tsconfig.jsonexistam"emitDecoratorMetadata": truee"experimental