Explicitly setting type on window for Intercom in Typescript throws error

Viewed 1050

As per the discussion here, I have had to extend the window object in order to strongly type Intercom's window functionality.

Originally the code used to look like this:

  setCurrentRoute() {
    if (
      this.currentRoute.getValue().indexOf('website') > -1 ||
      this.currentRoute.getValue().indexOf('builder') > -1
    ) {
      (window as any).Intercom('update', {
        hide_default_launcher: true,
      });
    } else {
      (window as any).Intercom('update', {
        hide_default_launcher: false,
      });
    }
    localStorage.setItem('currentRoute', this.currentRoute.getValue());
  }

But as I am trying to leverage more of Typescript's type safety features, it now looks like this:

  declare global {
    interface Window {
      Intercom(update: string, params: { hide_default_launcher: boolean }): void;
    }
  }

  setCurrentRoute(): void {
    if (this.currentRoute.getValue().indexOf('website') > -1 || this.currentRoute.getValue().indexOf('builder') > -1) {
      this.window.Intercom('update', {
        'hide_default_launcher': true
      });
    } else {
      this.window.Intercom('update', {
        'hide_default_launcher': false
      });
    }
    localStorage.setItem('currentRoute', this.currentRoute.getValue());
  }

However, I get the following error message:

ERROR TypeError: Cannot read property 'Intercom' of undefined
    at RouterService.push../src/app/shared/services/router.service.ts.RouterService.setCurrentRoute

How do I fix it?

2 Answers

Intercom With Typescript

Here's how I got typescript and intercom working:

  1. Include dependency yarn add -D @types/intercom-web
  2. Edit your tsconfig.json
{
  "compileOnSave": false,
  "compilerOptions": {
    ....,
    "types": [...., "@types/intercom-web"]
  }
}
  1. Now types will show in your code when referencing window.Intercom and the namespace Intercom_ will be globally available e.g: Intercom_.IntercomSettings

I managed to fix it by doing the following:

export interface RouterWindow extends Window {
  Intercom(update: string, params: { hide_default_launcher: boolean }): void;
}

  setCurrentRoute(): void {
    if (this.currentRoute.getValue().indexOf('website') > -1 || this.currentRoute.getValue().indexOf('builder') > -1) {
      (<RouterWindow>window).Intercom('update', {
        'hide_default_launcher': true
      });
    } else {
      (<RouterWindow>window).Intercom('update', {
        'hide_default_launcher': false
      });
    }
    localStorage.setItem('currentRoute', this.currentRoute.getValue());
  }
Related