Ferramentas de Desenvolvimento
Angular CLI

Erros de metadados AOT

Os seguintes são erros de metadados que você pode encontrar, com explicações e correções sugeridas.

Forma de expressão não suportada

HELPFUL: O compilador encontrou uma expressão que não entendeu ao avaliar metadados Angular.

Recursos de linguagem fora da sintaxe de expressão restrita do compilador podem produzir este erro, como visto no exemplo a seguir:

// ERRORexport class Fooish { … }const prop = typeof Fooish; // typeof não é válido em metadados  // notação de colchetes não é válida em metadados  { provide: 'token', useValue: { [prop]: 'value' } };

Você pode usar typeof e notação de colchetes em código de aplicação normal. Você apenas não pode usar esses recursos dentro de expressões que definem metadados Angular.

Evite este erro aderindo à sintaxe de expressão restrita do compilador ao escrever metadados Angular e fique atento a recursos novos ou incomuns do TypeScript.

Referência a um símbolo local (não exportado)

HELPFUL: Referência a um símbolo local (não exportado) 'nome do símbolo'. Considere exportar o símbolo.

O compilador encontrou uma referência a um símbolo definido localmente que não foi exportado ou não foi inicializado.

Aqui está um exemplo de provider do problema.

// ERRORlet foo: number; // nem exportado nem inicializado@Component({  selector: 'my-component',  template: … ,  providers: [    { provide: Foo, useValue: foo }  ]})export class MyComponent {}

O compilador gera a factory do component, que inclui o código do provider useValue, em um módulo separado. Aquele módulo factory não pode voltar a este módulo fonte para acessar a variável local (não exportada) foo.

Você poderia corrigir o problema inicializando foo.

let foo = 42; // inicializado

O compilador irá fazer fold da expressão no provider como se você tivesse escrito isto.

providers: [  { provide: Foo, useValue: 42 }]

Alternativamente, você pode corrigir exportando foo com a expectativa de que foo será atribuído em tempo de execução quando você realmente souber seu valor.

// CORRECTEDexport let foo: number; // exportado@Component({  selector: 'my-component',  template: … ,  providers: [    { provide: Foo, useValue: foo }  ]})export class MyComponent {}

Adicionar export frequentemente funciona para variáveis referenciadas em metadados como providers e animations porque o compilador pode gerar referências às variáveis exportadas nessas expressões. Ele não precisa dos valores dessas variáveis.

Adicionar export não funciona quando o compilador precisa do valor real para gerar código. Por exemplo, não funciona para a propriedade template.

// ERRORexport let someTemplate: string; // exportado mas não inicializado@Component({  selector: 'my-component',  template: someTemplate})export class MyComponent {}

O compilador precisa do valor da propriedade template agora mesmo para gerar a factory do component. A referência de variável sozinha é insuficiente. Prefixar a declaração com export apenas produz um novo erro, "Somente variáveis e constantes inicializadas podem ser referenciadas".

Somente variáveis e constantes inicializadas

HELPFUL: Somente variáveis e constantes inicializadas podem ser referenciadas porque o valor desta variável é necessário pelo template compiler.

O compilador encontrou uma referência a uma variável exportada ou campo estático que não foi inicializado. Ele precisa do valor dessa variável para gerar código.

O exemplo a seguir tenta definir a propriedade template do component para o valor da variável exportada someTemplate que é declarada mas não atribuída.

// ERRORexport let someTemplate: string;@Component({  selector: 'my-component',  template: someTemplate})export class MyComponent {}

Você também obteria este erro se importasse someTemplate de algum outro módulo e negligenciasse inicializá-la lá.

// ERROR - não inicializada lá tambémimport { someTemplate } from './config';@Component({  selector: 'my-component',  template: someTemplate})export class MyComponent {}

O compilador não pode esperar até o tempo de execução para obter as informações do template. Ele deve derivar estaticamente o valor da variável someTemplate do código fonte para que possa gerar a factory do component, que inclui instruções para construir o elemento baseado no template.

Para corrigir este erro, forneça o valor inicial da variável em uma cláusula inicializadora na mesma linha.

// CORRECTEDexport let someTemplate = '<h1>Greetings from Angular</h1>';@Component({  selector: 'my-component',  template: someTemplate})export class MyComponent {}

Referência a uma classe não exportada

HELPFUL: Referência a uma classe não exportada <nome da classe>. Considere exportar a classe.

Metadados referenciaram uma classe que não foi exportada.

Por exemplo, você pode ter definido uma classe e usado-a como um token de injeção em um array de providers mas negligenciado exportar essa classe.

// ERRORabstract class MyStrategy { }  providers: [    { provide: MyStrategy, useValue: … }  ]

Angular gera uma factory de classe em um módulo separado e essa factory só pode acessar classes exportadas. Para corrigir este erro, exporte a classe referenciada.

// CORRECTEDexport abstract class MyStrategy { }  providers: [    { provide: MyStrategy, useValue: … }  ]

Referência a uma função não exportada

HELPFUL: Metadados referenciaram uma função que não foi exportada.

Por exemplo, você pode ter definido uma propriedade useFactory de providers para uma função definida localmente que você negligenciou exportar.

// ERRORfunction myStrategy() { … }  providers: [    { provide: MyStrategy, useFactory: myStrategy }  ]

Angular gera uma factory de classe em um módulo separado e essa factory só pode acessar funções exportadas. Para corrigir este erro, exporte a função.

// CORRECTEDexport function myStrategy() { … }  providers: [    { provide: MyStrategy, useFactory: myStrategy }  ]

Chamadas de função não são suportadas

HELPFUL: Chamadas de função não são suportadas. Considere substituir a função ou lambda por uma referência a uma função exportada.

O compilador atualmente não suporta expressões de função ou funções lambda. Por exemplo, você não pode definir um useFactory de provider para uma função anônima ou arrow function como esta.

// ERROR  providers: [    { provide: MyStrategy, useFactory: function() { … } },    { provide: OtherStrategy, useFactory: () => { … } }  ]

Você também obtém este erro se chamar uma função ou método em um useValue de provider.

// ERRORimport { calculateValue } from './utilities';  providers: [    { provide: SomeValue, useValue: calculateValue() }  ]

Para corrigir este erro, exporte uma função do módulo e refira-se à função em um provider useFactory.

// CORRECTEDimport { calculateValue } from './utilities';export function myStrategy() { … }export function otherStrategy() { … }export function someValueFactory() {  return calculateValue();}  providers: [    { provide: MyStrategy, useFactory: myStrategy },    { provide: OtherStrategy, useFactory: otherStrategy },    { provide: SomeValue, useFactory: someValueFactory }  ]

Variável ou constante desestruturada não suportada

HELPFUL: Referenciar uma variável ou constante desestruturada exportada não é suportado pelo template compiler. Considere simplificar isso para evitar desestruturação.

O compilador não suporta referências a variáveis atribuídas por desestruturação.

Por exemplo, você não pode escrever algo como isto:

// ERRORimport { configuration } from './configuration';// atribuição desestruturada para foo e barconst {foo, bar} = configuration;  providers: [    {provide: Foo, useValue: foo},    {provide: Bar, useValue: bar},  ]

Para corrigir este erro, refira-se a valores não desestruturados.

// CORRECTEDimport { configuration } from './configuration';  providers: [    {provide: Foo, useValue: configuration.foo},    {provide: Bar, useValue: configuration.bar},  ]

Não foi possível resolver tipo

HELPFUL: O compilador encontrou um tipo e não pode determinar qual módulo exporta esse tipo.

Isso pode acontecer se você se referir a um tipo ambiente. Por exemplo, o tipo Window é um tipo ambiente declarado no arquivo global .d.ts.

Você obterá um erro se referenciá-lo no construtor do component, que o compilador deve analisar estaticamente.

// ERROR@Component({ })export class MyComponent {  constructor (private win: Window) { … }}

TypeScript entende tipos ambiente então você não os importa. O compilador Angular não entende um tipo que você negligencia exportar ou importar.

Neste caso, o compilador não entende como injetar algo com o token Window.

Não se refira a tipos ambiente em expressões de metadados.

Se você deve injetar uma instância de um tipo ambiente, você pode contornar o problema em quatro passos:

  1. Crie um token de injeção para uma instância do tipo ambiente.
  2. Crie uma factory function que retorna essa instância.
  3. Adicione um provider useFactory com essa factory function.
  4. Use @Inject para injetar a instância.

Aqui está um exemplo ilustrativo.

// CORRECTEDimport { Inject } from '@angular/core';export const WINDOW = new InjectionToken('Window');export function _window() { return window; }@Component({  providers: [    { provide: WINDOW, useFactory: _window }  ]})export class MyComponent {  constructor (@Inject(WINDOW) private win: Window) { … }}

O tipo Window no construtor não é mais um problema para o compilador porque ele usa o @Inject(WINDOW) para gerar o código de injeção.

Angular faz algo similar com o token DOCUMENT para que você possa injetar o objeto document do browser (ou uma abstração dele, dependendo da plataforma na qual a aplicação é executada).

import { Inject }   from '@angular/core';import { DOCUMENT } from '@angular/common';@Component({ … })export class MyComponent {  constructor (@Inject(DOCUMENT) private doc: Document) { … }}

Nome esperado

HELPFUL: O compilador esperava um nome em uma expressão que estava avaliando.

Isso pode acontecer se você usar um número como nome de propriedade como no exemplo a seguir.

// ERRORprovider: [{ provide: Foo, useValue: { 0: 'test' } }]

Mude o nome da propriedade para algo não numérico.

// CORRECTEDprovider: [{ provide: Foo, useValue: { '0': 'test' } }]

Nome de membro enum não suportado

HELPFUL: Angular não pôde determinar o valor do membro enum que você referenciou em metadados.

O compilador pode entender valores enum simples mas não valores complexos como aqueles derivados de propriedades computadas.

// ERRORenum Colors {  Red = 1,  White,  Blue = "Blue".length // computado}  providers: [    { provide: BaseColor,   useValue: Colors.White } // ok    { provide: DangerColor, useValue: Colors.Red }   // ok    { provide: StrongColor, useValue: Colors.Blue }  // ruim  ]

Evite se referir a enums com inicializadores complicados ou propriedades computadas.

Expressões tagged template não são suportadas

HELPFUL: Expressões tagged template não são suportadas em metadados.

O compilador encontrou uma expressão tagged template JavaScript ES2015 como a seguinte.

// ERRORconst expression = 'funky';const raw = String.raw`A tagged template ${expression} string`; template: '<div>' + raw + '</div>'

String.raw() é uma tag function nativa do JavaScript ES2015.

O compilador AOT não suporta expressões tagged template; evite-as em expressões de metadados.

Referência de símbolo esperada

HELPFUL: O compilador esperava uma referência a um símbolo no local especificado na mensagem de erro.

Este erro pode ocorrer se você usar uma expressão na cláusula extends de uma classe.