Angular @Output Named After A DOM Event

ID

javascript.angular_output_dom_event_name

Severity

high

Remediation Complexity

trivial

Remediation Risk

medium

Remediation Effort

low

Resource

Reliability

Language

JavaScript

Tags

angular, framework, naming, reliability

Description

Reports an Angular @Output whose binding name is a standard DOM event name:

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

@Component({ selector: "app-picker", template: "" })
export class PickerComponent {
  // Bad — (click) on this component now means two things.
  @Output() click = new EventEmitter<void>();

  // Bad — the alias is what the template writes.
  @Output("focus") gainedFocus = new EventEmitter<void>();
}
import { Component, EventEmitter, Output } from "@angular/core";

@Component({ selector: "app-picker", template: "" })
export class PickerComponent {
  // Good
  @Output() itemPicked = new EventEmitter<string>();
  @Output() gainedFocus = new EventEmitter<void>();
}

The name checked is the one a template writes: the alias when the decorator declares one, the property name otherwise.

Rationale

A template binds a native event and a component output with exactly the same syntax. On a component that declares an output named click, the binding (click)="pick()" no longer says which of the two it subscribes to.

Angular resolves it to the output. The native click the host element still fires therefore stops reaching that handler, and nothing in the template shows that this is happening — the reader has to open the component to find out.

The failure mode when the output is later removed is worse than a missing binding: the template keeps compiling, the native event takes over, and the handler starts firing on every click of anything inside the component.

Remediation

Name the output after the domain event, not the input gesture that happens to trigger it:

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

@Component({ selector: "app-picker", template: "" })
export class PickerComponent {
  @Output() itemPicked = new EventEmitter<string>();
}

Where the intent really is to re-expose the native event, do not re-emit it at all — let it bubble, and let the consumer bind it on the host element.

Configuration

Property Default Meaning

additionalEventNames

(empty)

Further names to treat as native events, for a project that binds events the built-in list does not carry.

© 2026 Xygeni. All rights reserved