Búsqueda de sitios web

angular - Tipo de Typescript BeforeInstallPromptEvent


¿Qué tipo de tipo debería usar al utilizar el evento beforeinstallprompt?

Intenté el tipo BeforeInstallPromptEvent, pero me dio un error:

export class PwaService {
  //promptEvent: BeforeInstallPromptEvent;
  promptEvent;
  constructor(private swUpdate: SwUpdate, platform: PlatformService) {
    if(platform.isBrowser()){
      swUpdate.available.subscribe(event =>  {
        /*if (askUserToUpdate()) {
          window.location.reload();
        }*/
      });
      window.addEventListener('beforeinstallprompt', event => {
        this.promptEvent = event;
      });
    }
  }

  install(): void {
    if(this.promptEvent){
      this.promptEvent.prompt();
    }
  }
}

Respuesta #1

El BeforeInstallPromptEvent es una API web no estándar y actualmente solo es compatible con Chrome y Android. Ni siquiera estoy seguro de si Google lo considera estable todavía, pero en cualquier caso no esperaría ver una definición de tipo oficial en la biblioteca DOM de TypeScript en un futuro próximo.

Sin embargo, puedes definir el tipo tú mismo, por ejemplo, en un archivo .d.ts. Yo uso la definición a continuación (comentarios de MDN), que parece ser lo suficientemente precisa en Chrome 68.

/**
 * The BeforeInstallPromptEvent is fired at the Window.onbeforeinstallprompt handler
 * before a user is prompted to "install" a web site to a home screen on mobile.
 *
 * @deprecated Only supported on Chrome and Android Webview.
 */
interface BeforeInstallPromptEvent extends Event {

  /**
   * Returns an array of DOMString items containing the platforms on which the event was dispatched.
   * This is provided for user agents that want to present a choice of versions to the user such as,
   * for example, "web" or "play" which would allow the user to chose between a web version or
   * an Android version.
   */
  readonly platforms: Array<string>;

  /**
   * Returns a Promise that resolves to a DOMString containing either "accepted" or "dismissed".
   */
  readonly userChoice: Promise<{
    outcome: 'accepted' | 'dismissed',
    platform: string
  }>;

  /**
   * Allows a developer to show the install prompt at a time of their own choosing.
   * This method returns a Promise.
   */
  prompt(): Promise<void>;

}

Respuesta #2

Mejora a la respuesta aceptada: también necesitas añadir una clave en WindowEventMap:

interface BeforeInstallPromptEvent extends Event {
  readonly platforms: string[];
  readonly userChoice: Promise<{
    outcome: "accepted" | "dismissed";
    platform: string;
  }>;
  prompt(): Promise<void>;
}

declare global {
  interface WindowEventMap {
    beforeinstallprompt: BeforeInstallPromptEvent;
  }
}

window.addEventListener("beforeinstallprompt", (e) => {}); // e is now typed

Tenga en cuenta que declare global {} es un envoltorio para tipar cosas globales en su código. También podría hacerlo en un archivo ambiental donde no exista la palabra clave import/export, entonces no hay necesidad del envoltorio. Pero es una buena práctica poner el código relacionado en el mismo archivo.

Artículos relacionados