Sharing my solution, because I was not completely satisfied with the rest. My problem with AfterViewChecked is that sometimes I'm scrolling up, and for some reason, this life hook gets called and it scrolls me down even if there were no new messages. I tried using OnChanges but this was an issue, which lead me to this solution. Unfortunately, using only DoCheck, it was scrolling down before the messages were rendered, which was not useful either, so I combined them so that DoCheck is basically indicating AfterViewChecked if it should call scrollToBottom.
Happy to receive feedback.
export class ChatComponent implements DoCheck, AfterViewChecked {
    @Input() public messages: Message[] = [];
    @ViewChild('scrollable') private scrollable: ElementRef;
    private shouldScrollDown: boolean;
    private iterableDiffer;
    constructor(private iterableDiffers: IterableDiffers) {
        this.iterableDiffer = this.iterableDiffers.find([]).create(null);
    }
    ngDoCheck(): void {
        if (this.iterableDiffer.diff(this.messages)) {
            this.numberOfMessagesChanged = true;
        }
    }
    ngAfterViewChecked(): void {
        const isScrolledDown = Math.abs(this.scrollable.nativeElement.scrollHeight - this.scrollable.nativeElement.scrollTop - this.scrollable.nativeElement.clientHeight) <= 3.0;
        if (this.numberOfMessagesChanged && !isScrolledDown) {
            this.scrollToBottom();
            this.numberOfMessagesChanged = false;
        }
    }
    scrollToBottom() {
        try {
            this.scrollable.nativeElement.scrollTop = this.scrollable.nativeElement.scrollHeight;
        } catch (e) {
            console.error(e);
        }
    }
}
chat.component.html
<div class="chat-wrapper">
    <div class="chat-messages-holder" #scrollable>
        <app-chat-message *ngFor="let message of messages" [message]="message">
        </app-chat-message>
    </div>
    <div class="chat-input-holder">
        <app-chat-input (send)="onSend($event)"></app-chat-input>
    </div>
</div>
chat.component.sass
.chat-wrapper
  display: flex
  justify-content: center
  align-items: center
  flex-direction: column
  height: 100%
  .chat-messages-holder
    overflow-y: scroll !important
    overflow-x: hidden
    width: 100%
    height: 100%