Skip to content

Commit

Permalink
feat(types): improve typing of .evaluate() (#6096)
Browse files Browse the repository at this point in the history
* feat(types): improve typing of `.evaluate()`

This is the start of the work to take the types from the
`@types/puppeteer` repository and port them into our repo so we can ship
our built-in types out the box.

This change types the `evaluate` function properly. It takes a generic
type which is the type of the function you're passing, and the arguments
and the return that you get back from the `evaluate` call are typed
correctly.
  • Loading branch information
jackfranklin committed Jun 25, 2020
1 parent a4d12a2 commit 46fc6ca
Show file tree
Hide file tree
Showing 22 changed files with 264 additions and 96 deletions.
2 changes: 2 additions & 0 deletions .eslintrc.js
Expand Up @@ -96,6 +96,8 @@ module.exports = {
"rules": {
"no-unused-vars": 0,
"@typescript-eslint/no-unused-vars": 2,
"func-call-spacing": 0,
"@typescript-eslint/func-call-spacing": 2,
"semi": 0,
"@typescript-eslint/semi": 2,
"@typescript-eslint/no-empty-function": 0,
Expand Down
18 changes: 17 additions & 1 deletion README.md
Expand Up @@ -292,9 +292,25 @@ Puppeteer creates its own browser user profile which it **cleans up on every run

- debug your test inside chromium like a boss!


<!-- [END debugging] -->


<!-- [START typescript] -->
## Usage with TypeScript

We have recently completed a migration to move the Puppeteer source code from JavaScript to TypeScript and we're currently working on shipping type definitions for TypeScript with Puppeteer's npm package.

Until this work is complete we recommend installing the Puppeteer type definitions from the [DefinitelyTyped](https://definitelytyped.org/) repository:

```bash
npm install --save-dev @types/puppeteer
```

The types that you'll see appearing in the Puppeteer source code are based off the great work of those who have contributed to the `@types/puppeteer` package. We really appreciate the hard work those people put in to providing high quality TypeScript definitions for Puppeteer's users.

<!-- [END typescript] -->


## Contributing to Puppeteer

Check out [contributing guide](https://github.com/puppeteer/puppeteer/blob/main/CONTRIBUTING.md) to get an overview of Puppeteer development.
Expand Down
6 changes: 3 additions & 3 deletions new-docs/puppeteer.elementhandle.__eval.md
Expand Up @@ -11,16 +11,16 @@ If `pageFunction` returns a Promise, then `frame.$$eval` would wait for the prom
<b>Signature:</b>

```typescript
$$eval<ReturnType extends any>(selector: string, pageFunction: Function | string, ...args: unknown[]): Promise<ReturnType>;
$$eval<ReturnType extends any>(selector: string, pageFunction: EvaluateFn | string, ...args: SerializableOrJSHandle[]): Promise<ReturnType>;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| selector | string | |
| pageFunction | Function \| string | |
| args | unknown\[\] | |
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
<b>Returns:</b>
Expand Down
6 changes: 3 additions & 3 deletions new-docs/puppeteer.elementhandle._eval.md
Expand Up @@ -11,16 +11,16 @@ If `pageFunction` returns a Promise, then `frame.$eval` would wait for the promi
<b>Signature:</b>

```typescript
$eval<ReturnType extends any>(selector: string, pageFunction: Function | string, ...args: unknown[]): Promise<ReturnType>;
$eval<ReturnType extends any>(selector: string, pageFunction: EvaluateFn | string, ...args: SerializableOrJSHandle[]): Promise<ReturnType>;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| selector | string | |
| pageFunction | Function \| string | |
| args | unknown\[\] | |
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
<b>Returns:</b>
Expand Down
12 changes: 12 additions & 0 deletions new-docs/puppeteer.evaluatefn.md
@@ -0,0 +1,12 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [puppeteer](./puppeteer.md) &gt; [EvaluateFn](./puppeteer.evaluatefn.md)

## EvaluateFn type


<b>Signature:</b>

```typescript
export declare type EvaluateFn<T = any> = string | ((arg1: T, ...args: any[]) => any);
```
12 changes: 12 additions & 0 deletions new-docs/puppeteer.evaluatefnreturntype.md
@@ -0,0 +1,12 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [puppeteer](./puppeteer.md) &gt; [EvaluateFnReturnType](./puppeteer.evaluatefnreturntype.md)

## EvaluateFnReturnType type


<b>Signature:</b>

```typescript
export declare type EvaluateFnReturnType<T extends EvaluateFn> = T extends (...args: any[]) => infer R ? R : unknown;
```
6 changes: 3 additions & 3 deletions new-docs/puppeteer.frame.__eval.md
Expand Up @@ -7,16 +7,16 @@
<b>Signature:</b>

```typescript
$$eval<ReturnType extends any>(selector: string, pageFunction: Function | string, ...args: unknown[]): Promise<ReturnType>;
$$eval<ReturnType extends any>(selector: string, pageFunction: EvaluateFn | string, ...args: SerializableOrJSHandle[]): Promise<ReturnType>;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| selector | string | |
| pageFunction | Function \| string | |
| args | unknown\[\] | |
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
<b>Returns:</b>
Expand Down
6 changes: 3 additions & 3 deletions new-docs/puppeteer.frame._eval.md
Expand Up @@ -7,16 +7,16 @@
<b>Signature:</b>

```typescript
$eval<ReturnType extends any>(selector: string, pageFunction: Function | string, ...args: unknown[]): Promise<ReturnType>;
$eval<ReturnType extends any>(selector: string, pageFunction: EvaluateFn | string, ...args: SerializableOrJSHandle[]): Promise<ReturnType>;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| selector | string | |
| pageFunction | Function \| string | |
| args | unknown\[\] | |
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
<b>Returns:</b>
Expand Down
8 changes: 4 additions & 4 deletions new-docs/puppeteer.jshandle.evaluate.md
Expand Up @@ -9,19 +9,19 @@ This method passes this handle as the first argument to `pageFunction`<!-- -->.
<b>Signature:</b>

```typescript
evaluate<ReturnType extends any>(pageFunction: Function | string, ...args: unknown[]): Promise<ReturnType>;
evaluate<T extends EvaluateFn>(pageFunction: T | string, ...args: SerializableOrJSHandle[]): Promise<EvaluateFnReturnType<T>>;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| pageFunction | Function \| string | |
| args | unknown\[\] | |
| pageFunction | T \| string | |
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
<b>Returns:</b>
Promise&lt;ReturnType&gt;
Promise&lt;[EvaluateFnReturnType](./puppeteer.evaluatefnreturntype.md)<!-- -->&lt;T&gt;&gt;
## Example
Expand Down
12 changes: 12 additions & 0 deletions new-docs/puppeteer.jsonarray.md
@@ -0,0 +1,12 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [puppeteer](./puppeteer.md) &gt; [JSONArray](./puppeteer.jsonarray.md)

## JSONArray type


<b>Signature:</b>

```typescript
export declare type JSONArray = Serializable[];
```
12 changes: 12 additions & 0 deletions new-docs/puppeteer.jsonobject.md
@@ -0,0 +1,12 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [puppeteer](./puppeteer.md) &gt; [JSONObject](./puppeteer.jsonobject.md)

## JSONObject interface


<b>Signature:</b>

```typescript
export interface JSONObject
```
6 changes: 6 additions & 0 deletions new-docs/puppeteer.md
Expand Up @@ -52,6 +52,7 @@
| [BrowserFetcherOptions](./puppeteer.browserfetcheroptions.md) | |
| [ClickOptions](./puppeteer.clickoptions.md) | |
| [ConsoleMessageLocation](./puppeteer.consolemessagelocation.md) | |
| [JSONObject](./puppeteer.jsonobject.md) | |
| [KeyDefinition](./puppeteer.keydefinition.md) | Copyright 2017 Google Inc. All rights reserved.<!-- -->Licensed under the Apache License, Version 2.0 (the 'License'); you may not use this file except in compliance with the License. You may obtain a copy of the License at<!-- -->http://www.apache.org/licenses/LICENSE-2.0<!-- -->Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. |
| [Metrics](./puppeteer.metrics.md) | |
| [PressOptions](./puppeteer.pressoptions.md) | |
Expand All @@ -73,7 +74,12 @@
| Type Alias | Description |
| --- | --- |
| [ConsoleMessageType](./puppeteer.consolemessagetype.md) | The supported types for console messages. |
| [EvaluateFn](./puppeteer.evaluatefn.md) | |
| [EvaluateFnReturnType](./puppeteer.evaluatefnreturntype.md) | |
| [JSONArray](./puppeteer.jsonarray.md) | |
| [KeyInput](./puppeteer.keyinput.md) | |
| [MouseButtonInput](./puppeteer.mousebuttoninput.md) | |
| [PuppeteerErrors](./puppeteer.puppeteererrors.md) | |
| [Serializable](./puppeteer.serializable.md) | |
| [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md) | |

6 changes: 3 additions & 3 deletions new-docs/puppeteer.page.__eval.md
Expand Up @@ -7,16 +7,16 @@
<b>Signature:</b>

```typescript
$$eval<ReturnType extends any>(selector: string, pageFunction: Function | string, ...args: unknown[]): Promise<ReturnType>;
$$eval<ReturnType extends any>(selector: string, pageFunction: EvaluateFn | string, ...args: SerializableOrJSHandle[]): Promise<ReturnType>;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| selector | string | |
| pageFunction | Function \| string | |
| args | unknown\[\] | |
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
<b>Returns:</b>
Expand Down
6 changes: 3 additions & 3 deletions new-docs/puppeteer.page._eval.md
Expand Up @@ -7,16 +7,16 @@
<b>Signature:</b>

```typescript
$eval<ReturnType extends any>(selector: string, pageFunction: Function | string, ...args: unknown[]): Promise<ReturnType>;
$eval<ReturnType extends any>(selector: string, pageFunction: EvaluateFn | string, ...args: SerializableOrJSHandle[]): Promise<ReturnType>;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| selector | string | |
| pageFunction | Function \| string | |
| args | unknown\[\] | |
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
<b>Returns:</b>
Expand Down
12 changes: 12 additions & 0 deletions new-docs/puppeteer.serializable.md
@@ -0,0 +1,12 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [puppeteer](./puppeteer.md) &gt; [Serializable](./puppeteer.serializable.md)

## Serializable type


<b>Signature:</b>

```typescript
export declare type Serializable = number | string | boolean | null | JSONArray | JSONObject;
```
12 changes: 12 additions & 0 deletions new-docs/puppeteer.serializableorjshandle.md
@@ -0,0 +1,12 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [puppeteer](./puppeteer.md) &gt; [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)

## SerializableOrJSHandle type


<b>Signature:</b>

```typescript
export declare type SerializableOrJSHandle = Serializable | JSHandle;
```
1 change: 1 addition & 0 deletions src/api-docs-entry.ts
Expand Up @@ -48,3 +48,4 @@ export * from './common/Errors';
export * from './common/Tracing';
export * from './common/WebWorker';
export * from './common/USKeyboardLayout';
export * from './common/EvalTypes';
9 changes: 5 additions & 4 deletions src/common/DOMWorld.ts
Expand Up @@ -24,6 +24,7 @@ import { TimeoutSettings } from './TimeoutSettings';
import { MouseButtonInput } from './Input';
import { FrameManager, Frame } from './FrameManager';
import { getQueryHandlerAndSelector, QueryHandler } from './QueryHandler';
import { EvaluateFn, SerializableOrJSHandle } from './EvalTypes';
import { isNode } from '../environment';

// This predicateQueryHandler is declared here so that TypeScript knows about it
Expand Down Expand Up @@ -155,17 +156,17 @@ export class DOMWorld {

async $eval<ReturnType extends any>(
selector: string,
pageFunction: Function | string,
...args: unknown[]
pageFunction: EvaluateFn | string,
...args: SerializableOrJSHandle[]
): Promise<ReturnType> {
const document = await this._document();
return document.$eval<ReturnType>(selector, pageFunction, ...args);
}

async $$eval<ReturnType extends any>(
selector: string,
pageFunction: Function | string,
...args: unknown[]
pageFunction: EvaluateFn | string,
...args: SerializableOrJSHandle[]
): Promise<ReturnType> {
const document = await this._document();
const value = await document.$$eval<ReturnType>(
Expand Down
58 changes: 58 additions & 0 deletions src/common/EvalTypes.ts
@@ -0,0 +1,58 @@
/**
* Copyright 2020 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { JSHandle } from './JSHandle';

/**
* @public
*/
export type EvaluateFn<T = any> = string | ((arg1: T, ...args: any[]) => any);
/**
* @public
*/
export type EvaluateFnReturnType<T extends EvaluateFn> = T extends (
...args: any[]
) => infer R
? R
: unknown;

/**
* @public
*/
export type Serializable =
| number
| string
| boolean
| null
| JSONArray
| JSONObject;

/**
* @public
*/
export type JSONArray = Serializable[];

/**
* @public
*/
export interface JSONObject {
[key: string]: Serializable;
}

/**
* @public
*/
export type SerializableOrJSHandle = Serializable | JSHandle;

0 comments on commit 46fc6ca

Please sign in to comment.