“beforeinstallprompt”的正确类型是什么

时间:2021-02-25 14:20:42

标签: reactjs typescript

如何仅使用 beforeinstallpromptBeforeInstallPromptEvent 的窗口上放置的事件侦听器找到正确的类型 给出错误 Cannot find name 'BeforeInstallPromptEvent'.ts(2304)

import React, { useState, useEffect } from 'react';
import { Button } from './button';

function InstallPWA() {
  const [loading, setLoading] = useState(false);
  const [deferredPrompt, setDeferredPrompt] = useState<BeforeInstallPromptEvent>();
  const [isSupportedBrowser, setIsSupportedBrowser] = useState(false);
  const [hasPrompt, setHasPrompt] = useState(false);
  const [eligibleUser, setEligibleUser] = useState(true);

  const install = async () => {
    setLoading(true);
    const relatedApps = await (navigator as any).getInstalledRelatedApps();
    const isIOS =
      navigator.userAgent.includes('iPhone') ||
      navigator.userAgent.includes('iPad') ||
      (navigator.userAgent.includes('Macintosh') &&
        typeof navigator.maxTouchPoints === 'number' &&
        navigator.maxTouchPoints > 2);

    setEligibleUser(
      isSupportedBrowser && relatedApps.length < 1 && (hasPrompt || isIOS)
    );

    if (deferredPrompt) {
      deferredPrompt.prompt();
      const { outcome } = await deferredPrompt.userChoice;
      if (outcome === 'accepted') {
        setLoading(false);
        setEligibleUser(false);
      } else {
        setLoading(false);
        deferredPrompt = null;
      }
    } else {
      setLoading(false);
    }
  };

  const handlePrompt = (e: BeforeInstallPromptEvent) => {
//                                ^================================ This cant be found
    console.log('handle prompt');
    console.log(e);
    setIsSupportedBrowser(true);
    setHasPrompt(true);
    if (e) {
      setDeferredPrompt(e);
      e.preventDefault();
    }
  };

  useEffect(() => {
    window.addEventListener('beforeinstallprompt', handlePrompt);
    return () => {
      window.removeEventListener('beforeinstallprompt', handlePrompt);
    };
  }, []);

  return (
    <div className='InstallPWA'>
      {eligibleUser && (
        <Button click={install} size='small' text='Install' loading={loading} />
      )}
    </div>
  );
}

export { InstallPWA };

更新

我尝试在不使用状态的情况下保存事件对象

import React, { useState, useEffect } from 'react';
import { Button } from './button';

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

function InstallPWA() {
  const [loading, setLoading] = useState(false);
  let deferredPrompt: BeforeInstallPromptEvent | null = null;
  const [isSupportedBrowser, setIsSupportedBrowser] = useState(false);
  const [hasPrompt, setHasPrompt] = useState(false);
  const [eligibleUser, setEligibleUser] = useState(true);

  const install = async () => {
    setLoading(true);
    const relatedApps = await (navigator as any).getInstalledRelatedApps();
    const isIOS =
      navigator.userAgent.includes('iPhone') ||
      navigator.userAgent.includes('iPad') ||
      (navigator.userAgent.includes('Macintosh') &&
        typeof navigator.maxTouchPoints === 'number' &&
        navigator.maxTouchPoints > 2);

    setEligibleUser(
      isSupportedBrowser && relatedApps.length < 1 && (hasPrompt || isIOS)
    );

    if (deferredPrompt) {
      deferredPrompt.prompt();
      const { outcome } = await deferredPrompt.userChoice;
      if (outcome === 'accepted') {
        setLoading(false);
        setEligibleUser(false);
      } else {
        setLoading(false);
        deferredPrompt = null;
      }
    } else {
      setLoading(false);
    }
  };

  const handlePrompt = (e: BeforeInstallPromptEvent) => {
    setIsSupportedBrowser(true);
    setHasPrompt(true);
    if (e) {
      deferredPrompt = e;
      e.preventDefault();
    }
  };

  useEffect(() => {
    window.addEventListener('beforeinstallprompt', handlePrompt);
    return () => {
      window.removeEventListener('beforeinstallprompt', handlePrompt);
    };
  }, []);

  return (
    <div className='InstallPWA'>
      {eligibleUser && (
        <Button click={install} size='small' text='Install' loading={loading} />
      )}
    </div>
  );
}

export { InstallPWA };

但错误是

No overload matches this call.
  Overload 1 of 3, '(type: "input" | "progress" | "select" | "click" | "scroll" | "error" | "abort" | "afterprint" | "beforeprint" | "beforeunload" | "blur" | "canplay" | "canplaythrough" | "change" | "compassneedscalibration" | ... 119 more ... | "unhandledrejection", listener: (this: Window, ev: MouseEvent | ... 22 more ... | PromiseRejectionEvent) => any, options?: boolean | ... 1 more ... | undefined): void', gave the following error.
    Argument of type '"beforeinstallprompt"' is not assignable to parameter of type '"input" | "progress" | "select" | "click" | "scroll" | "error" | "abort" | "afterprint" | "beforeprint" | "beforeunload" | "blur" | "canplay" | "canplaythrough" | "change" | "compassneedscalibration" | ... 119 more ... | "unhandledrejection"'.
  Overload 2 of 3, '(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void', gave the following error.
    Argument of type '(e: BeforeInstallPromptEvent) => void' is not assignable to parameter of type 'EventListenerOrEventListenerObject'.
      Type '(e: BeforeInstallPromptEvent) => void' is not assignable to type 'EventListener'.
        Types of parameters 'e' and 'evt' are incompatible.
          Type 'Event' is missing the following properties from type 'BeforeInstallPromptEvent': platforms, userChoice, prompt
  Overload 3 of 3, '(type: "error" | "message" | "offline" | "online" | "languagechange" | "messageerror" | "rejectionhandled" | "unhandledrejection", listener: (this: DedicatedWorkerGlobalScope, ev: Event | ErrorEvent | MessageEvent<...> | PromiseRejectionEvent) => any, options?: boolean | ... 1 more ... | undefined): void', gave the following error.
    Argument of type '"beforeinstallprompt"' is not assignable to parameter of type '"error" | "message" | "offline" | "online" | "languagechange" | "messageerror" | "rejectionhandled" | "unhandledrejection"'.  TS2769

0 个答案:

没有答案
相关问题