I think that the better answer for angular(6+) is the Ajay Gupta's one. Because Validators.email like Krishnadas's answer let pass things like email@email. But I searched for better patterns, and in this answer finded one that is so much better, and is explained.
And if you use a prettier, or something that formats your code (and is always better), your regex pattern is better to be between / / characters
so:
this.form = this.formBuilder.group({
email: ['', [
       Validators.required,
       Validators.pattern(/^[\w]{1,}[\w.+-]{0,}@[\w-]{1,}([.][a-zA-Z]{2,}|[.][\w-]{2,}[.][a-zA-Z]{2,})$/)
       ]]
});
You can catch the errors like this:
<div *ngIf="(email.invalid && email.touched) || email.dirty">
    <small *ngIf="email.errors?.required" class="text-danger">email is required</small>
    <small *ngIf="email.errors?.pattern" class="text-danger">Please provide a valid email address</small>
</div>
You can make your own validators that extends Validators, to make your own email validator:
export class CommonValidators extends Validators {
  static email(control: FormControl): ValidationErrors | null {
    const value: string = control.value;
    if (_.isEmpty(value)) {
      return null;
    }
    const pattern = /^[\w]{1,}[\w.+-]{0,}@[\w-]{1,}([.][a-zA-Z]{2,}|[.][\w-]{2,}[.][a-zA-Z]{2,})$/;
    if (!value.match(pattern)) {
      return { email: true };
    }
    return null;
  }
}
Dirty is true, Touched is true and valid is false. But in actual fact everythink is fine, because the input field is empty. – HansPeter Mar 08 '18 at 21:52