javascript - 在 Typescript 中,如何在存储然后从数组访问所述对象时维护对象类型?

标签 javascript arrays typescript puppeteer

在 typescript 中,我注意到当我将一个复杂的对象放入数组中时,当我尝试从数组中访问该对象时,它会丢失其类型,而只是变成对象类型。

例如

let myArray = return await this.browser.evaluate((sel: string) => Array.from(document.querySelectorAll(sel)), selector)

document.querySelectorAll(sel)返回 NodeList<Element>这是 ArrayLike . Array.from应该转换 NodeList到一个元素数组中,但是一旦数组形成,所有数组元素都会失去它们的 Element类型

我有一个函数只接受 Element 类型的参数,但是当我尝试传入 myArray[0] 时作为所述函数的参数,我收到错误:Error: Unsupported target type: object

我已经尝试了很多不同的方法来尝试让数组保持其对象类型,以至于很难解释每一种方法。我想知道如何创建 Element 的数组s 并让它们继续为 Element s 稍后访问时而不是通用 object

这里是我所做测试的更多背景信息

我要去这个页面:https://www.w3schools.com/html/html_tables.asp 我传递给评估的选择器是 table[id="customers"] tbody tr这应该与表格中出现的 6 行匹配。

let test = await this.browser.evaluate((sel: string) => 
Array.from(document.querySelectorAll(sel)), selector)
console.log('testy1: ', test)
console.log('testy2: ', test[0])
console.log('testy3: ', typeof(test[0]))

当我运行上面的代码时,这是我在控制台日志中得到的输出:

testy1:  [ {}, {}, {}, {}, {}, {}, {} ]
testy2:  {}
testy3:  object

它似乎匹配从页面中抓取元素,因为它正确返回了 6 个元素。但也许问题是返回的对象是空的?我不确定。

我想我的问题可能与这个问题有关:puppeteer page.evaluate querySelectorAll return empty objects

但是这个问题的解决方案对我不起作用,因为 href 不是对象类型的属性 Element

最佳答案

这里的问题是您传递给 page.evaluate 的函数是在浏览器上下文中运行的(在浏览器页面内)。为了将结果从浏览器上下文发送到 Node.js 环境,结果被序列化。

请参阅文档中page.evaluate 的返回类型:

returns: Promise<Serializable> Promise which resolves to the return value of pageFunction

这里的Serializable是指你的数据会通过JSON.stringify传递给Node.js环境,在那里自动为你解析。但是,此过程将删除对象的任何不可序列化的属性。这就是您最终得到许多空对象的原因。

在 puppeteer 中获取元素句柄

要获取页面上元素的句柄,您需要使用 page.$ ,它创建一个对象(在您的 Node.js 环境中),该对象链接到浏览器上下文中的元素。这些类型的句柄也可以传递给 page.evaluate 调用。要查询多个元素,可以使用函数 page.$$ .

代码示例

这是一个示例,它首先查询一个元素,然后将元素句柄传递给评估函数以读取属性。

const elementHandle = await page.$('a');
const result = await page.evaluate(el => el.href, elementHandle);

TypeScript 的使用

关于 TypeScript 的问题是,TypeScript 无法在这种情况下正确预测类型。对于 TypeScript 编译器,这看起来像是一个普通的函数调用,而实际上,该函数被发送到客户端以供执行。因此,在这种情况下你必须自己转换类型,否则 Typescript 将假定 any 作为参数类型:

const elementHandle = await page.$('a');
const result = await page.evaluate((el: { href: string }) => el.href, elementHandle);

关于javascript - 在 Typescript 中,如何在存储然后从数组访问所述对象时维护对象类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56188757/

相关文章:

javascript - React 中的 typescript : State will not be placed in the constructor will cause an error

typescript - tsc --watch 在 tsconfig.json 中存在 outDir 时不更新文件

typescript - ESLint 在包含的 tsconfig 文件上抛出错误

javascript - 根据选择下拉列表中单击的选项更改标记

javascript - 在 d3 中用 2 种颜色填充 'rect' 背景

java - 想要通过 java jpanel 数组创建像 facebook 帖子这样的卡片 View

javascript - JavaScript 中的排序函数在某些情况下无法给出正确的输出?

php - 将 PHP 和 JSON 编码转换为 Javascript 日期

javascript - 使用 css3 : opacity transition 处理移动设备上的 "Rasterize Paint"延迟

java - 二分查找中的最大键比较 (1+log(n)) 为何不是 log(n)?