如何消除Puppeteer eval中的TypeScript错误?
Puppeteer全局注入变量的类型注解问题解决
问题描述
我有一段简单的Puppeteer脚本:
export async function inspectWebpage(source) { const b = await getBrowser() const p = await b.newPage() await p.goto(path) const script = fs.readFileSync( 'host/code/node/puppeteer/crawl.js', 'utf-8', ) await p.evaluate(script) let data = await p.evaluate(() => task.getWebpageData()) await b.close() return data }
每次运行都会触发TypeScript错误:
Cannot find name 'task'.ts(2304)
其中task是通过webpack构建后全局注入到Puppeteer上下文的对象。类似地,当访问window上的自定义属性(如window.X.y)时,会出现:
Property 'X' does not exist on type 'Window & typeof globalThis'.
需要解决这类全局注入变量的类型注解问题。
解决方案
1. 扩展全局类型声明(推荐)
通过扩展TypeScript的全局接口,为注入的变量添加类型定义,步骤如下:
- 在项目根目录创建一个类型声明文件(如
global.d.ts),内容如下:
// global.d.ts declare global { // 扩展Window接口,添加自定义属性X的类型 interface Window { X: { y: string; // 根据实际业务调整类型,比如number、object等 }; } // 声明全局变量task的类型 const task: { getWebpageData: () => Record<string, any>; // 替换为实际返回的数据结构 }; } // 必须导出空对象,让TypeScript识别这是一个模块文件 export {};
- 确保该文件被
tsconfig.json的include数组包含(默认会自动识别根目录下的.d.ts文件,若未包含,手动添加路径即可)。
这种方法能让TypeScript识别全局变量,同时提供完整的类型提示,保证代码的类型安全性。
2. 使用类型断言(临时方案)
如果不想修改全局类型,可以在p.evaluate的回调中直接使用类型断言绕过类型检查:
// 处理task变量 let data = await p.evaluate(() => (task as any).getWebpageData()); // 处理window.X.y await p.evaluate(() => (window as any).X.y);
这种方式简单快捷,但会失去类型校验能力,适合临时调试或快速修复场景。
3. 传递变量到evaluate上下文(可选)
若变量支持序列化,可将其作为参数传递给p.evaluate(注:函数等不可序列化对象无法直接传递,因此这种方法对webpack注入的全局task可能不适用):
await p.evaluate((taskInstance) => taskInstance.getWebpageData(), task);
内容的提问来源于stack exchange,提问作者Lance Pollard
相关产品推荐
相关产品推荐

