Could not resolve type Document in angular5

You'll get this error if using something like

@Inject(DOCUMENT) document: Document

with your compiler settings in your tsconfig.json set to

"angularCompilerOptions": {
  "strictMetadataEmit": true
}

It turns out that the angular compiler doesn't understand the type Document when working out the metadata for injectable parameters, even though it understands the injection token DOCUMENT, and Typescript understands type Document.

This is documented here: https://github.com/angular/angular/issues/20351

The workaround that I use is:

@Injectable({
  providedIn: 'root'
})
class MyService {

  constructor(@Inject(DOCUMENT) document?: any) {
    this._document = document as Document;
  }

  private _document?: Document;

...

This uses any for the injection signature (making angular happy), but gives you Typescript types within the class.


Note: This is no longer an issue with Ivy on Angular 9 or later. You can just use:

constructor(
  @Inject(DOCUMENT) readonly document: Document
) {}

You can add "/** @dynamic */" before your component's decorator:

/** @dynamic */
@Component({

to suppress the error as mentioned here https://github.com/angular/angular/issues/20351#issuecomment-344009887 and here https://angular.io/guide/aot-compiler#strictmetadataemit


EDIT: As the comments state, it is a bad practice. To use at your own risk. ;)

You can directly use document in typescript without any import.

Just do: document.body.classList.add("any_class");.