output() — Strongly Typed Custom Events
Outputs — Emitting Events to Parent
The output() function declares a custom event a parent can listen to with the same parentheses-binding syntax as native DOM events.
What you'll learn
- Declare an output() and emit a value
- Listen in the parent with (event)
- Compare to the legacy EventEmitter pattern
If input() is data flowing in, output() is events flowing out. Children declare events, parents listen.
Declaring an Output
import { Component, output } from '@angular/core';
interface User { id: string; name: string; }
@Component({
selector: 'app-form',
standalone: true,
template: `<button (click)="save()">Save</button>`,
})
export class FormComponent {
saved = output<User>();
save() {
this.saved.emit({ id: '1', name: 'Ada' });
}
} The generic on output<User>() types the payload. Calling .emit() with the wrong shape is a compile error.
Listening in the Parent
<app-form (saved)="handle($event)" /> $event is whatever you passed to emit(). Angular infers its type from the output’s generic.
The Legacy Pattern
Before output(), you used @Output() and EventEmitter.
import { Component, Output, EventEmitter } from '@angular/core';
@Component({ /* ... */ })
export class FormComponent {
@Output() saved = new EventEmitter<User>();
save() { this.saved.emit({ id: '1', name: 'Ada' }); }
} output() is preferred — it removes the dependency on EventEmitter (which is just an RxJS Subject) and produces cleaner types.