puppeteer - 帶有回調函數和參數的 Typescript 泛型類型(封裝 puppeteer)
我正在嘗試為 Puppeteer 做一些封裝函數。但我在處理 TypeScript 的類型時遇到了困難。
基本上,Puppeteer 允許以這種方式注入一些程式碼
page.$eval("selector" ,(element, args) => {}, someArgs)我想做一個函數,它允許使用回調並傳遞 "someArgs"。我的選擇器保持不變。
這是我的嘗試(下面也附有 stackBlitz 連結以獲得詳細重現)
import puppeteer from 'puppeteer';
(async () => {
const browser = await puppeteer.launch({});
const page = await browser.newPage();
const runForVideo = <T extends any[]>(
cb: (video: HTMLVideoElement, ...args: [...T, ...undefined[]]) => void,
...args: T
) => page.$eval('video', (video, ...args) => cb(video, ...args), args); // ...args are yielding :'(
// Argument of type '[FlattenHandle<T>]' is not assignable to parameter of type '[...T, ...undefined[]]'.
// Source provides no match for variadic element at position 0 in target.(2345)
await runForVideo((video, a) => {
// a is undefined
});
await runForVideo((video, volume) => {
video.volume = volume;
}, 5);
await runForVideo(
(video, volume, text) => {
video.volume = volume;
console.log(text);
},
5,
'hello'
);
})();
我希望那個 runForVideo 的第一個參數回調只有在 runForVideo 有一個(或多個)參數時才有第二個參數,並且類型相同。
有沒有什麼想法可以繼續進行?
謝謝
附註:我在這裡添加了一個完整的範例:https://stackblitz.com/edit/node-zxyvaa?file=index.ts,你可以看到這個方法工作正常,只是 cb 生成的是它需要的 FlattenHandle
答案#1
你得到的錯誤是你的回呼類型與 puppetter 的回呼類型不相容。puppeteer 期望一個與 string | EvaluateFuncWith<Element,V> 相容的類型。如果你將你的函數簽名改成這個:
const runForVideo = <T extends any[]>(
cb: EvaluateFuncWith<HTMLVideoElement, [...T]>,
...args: T
) => page.$eval('video', cb, ...args);
它應該會如預期般運作。
Stackblitz
