如何仅使用 beforeinstallprompt
为 BeforeInstallPromptEvent
的窗口上放置的事件侦听器找到正确的类型
给出错误
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