Componentsbeginner

Input and Output Properties

Explain how @Input and @Output enable one-directional parent-child data flow and event communication.

@Input() and @Output() are the backbone of Angular's component communication model, and they exist to enforce a predictable, one-directional data flow: data flows down from parent to child via inputs, and events flow up from child to parent via outputs. Interviewers ask about this early because it's foundational, but they often push into edge cases — like whether mutating an object passed via @Input() from inside the child is a good idea (it isn't, generally, since it breaks the unidirectional mental model and can cause subtle bugs).

Think of a factory assembly line: raw materials (inputs) are handed down to a workstation, and finished parts or alerts (outputs) get sent back up the line — the workstation never reaches backward into the supply chain to change what's above it.

Key Concepts

1
@Output() properties are typed as EventEmitter<T>, which is a thin wrapper around an RxJS Subject that only supports .emit() — it's deliberately not a full Observable API surface for the emitting side, even though consumers subscribe to it like one via the (eventName) template syntax.
@Output()EventEmitter<T>Subject.emit()(eventName)
2
Modern Angular (17.1+) introduces signal-based alternatives: input() for inputs and output() for outputs, which integrate more naturally with signals and computed values, and are gradually becoming the idiomatic choice over the decorator-based API, especially in new codebases adopting signals throughout.
input()output()
3
A sharp interview answer also covers input aliasing (@Input('aliasName')), required inputs (@Input({ required: true }) or input.required()), and why making inputs required at the type level catches a whole category of "forgot to pass a required prop" bugs at compile time rather than runtime.
@Input('aliasName')@Input({ required: true })input.required()