Angular outputs Metadata Array

ID

javascript.angular_outputs_metadata

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Best Practice

Language

JavaScript

Tags

angular, best-practice, framework, maintainability

Description

Reports an outputs array in @Component or @Directive metadata — the string-typed alternative to decorating the emitter itself:

import { Component, EventEmitter } from "@angular/core";

// Bad
@Component({ selector: "app-editor", template: "", outputs: ["saved", "cancel: cancelled"] })
export class EditorComponent {
  saved = new EventEmitter<void>();
  cancel = new EventEmitter<void>();
}
import { Component, EventEmitter, Output } from "@angular/core";

// Good
@Component({ selector: "app-editor", template: "" })
export class EditorComponent {
  @Output() saved = new EventEmitter<void>();
  @Output() cancelled = new EventEmitter<void>();
}

Rationale

The array names its emitters in strings, so nothing connects an entry to the member it is about:

  • Renaming or deleting the emitter leaves the entry behind and still compiling. Every template listening on that output then silently stops receiving anything.

  • Nothing in the class says the emitter is public API, so the next reader has to open the decorator to find out which of the members a template may subscribe to.

  • A refactoring tool cannot follow the link, so a rename that looks safe is not.

@Output() states the same thing on the emitter, where the compiler sees both halves at once and a rename carries the declaration with it.

Remediation

Move each entry onto its emitter and delete the array:

import { Component, EventEmitter, Output } from "@angular/core";

@Component({ selector: "app-editor", template: "" })
export class EditorComponent {
  @Output() saved = new EventEmitter<void>();
  @Output() cancelled = new EventEmitter<void>();
}

An entry written as "cancel: cancelled" also declares an alias. Prefer renaming the emitter to the name the template should listen on rather than carrying the alias over — see javascript.angular_output_alias.

© 2026 Xygeni. All rights reserved