TypeScript泛型实现Puppeteer包装函数的类型定义问题
解决Puppeteer封装
runForVideo的TypeScript类型匹配问题 完整实现代码
import type { Page } from 'puppeteer'; async function runForVideo<Params extends unknown[], Ret>( page: Page, pageFunction: (video: HTMLVideoElement, ...args: Params) => Ret | Promise<Ret>, ...args: Params ): Promise<Ret> { return page.$eval('video', pageFunction, ...args); }
类型问题解析
你遇到的Argument of type '[FlattenHandle<T>]' is not assignable to parameter of type '[...T, ...undefined[]]'错误,核心是对Puppeteer的$eval类型逻辑理解偏差:
$eval的回调运行在浏览器上下文中,第一个参数是匹配到的DOM元素(这里是HTMLVideoElement),而非Node.js侧的ElementHandle- 之前的泛型定义错误绑定了元素的Handle类型,导致参数类型链断裂
类型安全的使用示例
// 示例1:设置播放速度并返回视频时长 const duration = await runForVideo(page, (video, speed) => { video.playbackRate = speed; return video.duration; }, 2.0); // TypeScript自动推导:Params = [number],speed类型为number,duration类型为number // 示例2:传入字符串设置视频源 await runForVideo(page, (video, src) => { video.src = src; }, 'https://example.com/video.mp4'); // 参数类型不匹配时会直接报错(比如传数字给src参数)
关键优势
- 自动推导回调参数类型:传入的
args类型会自动同步到回调的参数列表 - 强类型约束:回调第一个参数固定为
HTMLVideoElement,避免类型歧义 - 返回值类型自动匹配:函数返回值类型与回调的返回值类型完全一致
内容的提问来源于stack exchange,提问作者ScreamZ
相关产品推荐
相关产品推荐

