Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript 4.9 does not build Playwright anymore #51619

Closed
mxschmitt opened this issue Nov 21, 2022 · 7 comments Β· Fixed by microsoft/playwright#19280
Closed

TypeScript 4.9 does not build Playwright anymore #51619

mxschmitt opened this issue Nov 21, 2022 · 7 comments Β· Fixed by microsoft/playwright#19280
Assignees
Labels
Needs Investigation This issue needs a team member to investigate its status.

Comments

@mxschmitt
Copy link
Member

Bug Report

πŸ”Ž Search Terms

conditional types, 4.9, infer, regression

πŸ•— Version & Regression Information

bad : 4.9.0-dev.20220827
not available on NPM : 4.9.0-dev.20220826
good : 4.9.0-dev.20220825

⏯ Playground Link

Wasn't able to make a small independent repro out of it, but these are the repro steps:

git clone https://github.com/microsoft/playwright
cd playwright
npm ci
# make it TypeScript 4.9 compatible
npm i -D @types/node@14.18.29
npm i -D playwright@4.9.0-dev.20220827
npm run tsc

πŸ™ Actual behavior

Does not transpile, a lot of weird errors which did not make sense to me.

πŸ™‚ Expected behavior

It compiles without any errors.

cc @andrewbranch @DanielRosenwasser since both interacted with Playwright and TypeScript before to try out the new RCs.

@mxschmitt
Copy link
Member Author

Looks similar to #51614 and #51540

@mxschmitt
Copy link
Member Author

mxschmitt commented Nov 28, 2022

Looks like #51621 fixes it, will confirm soon

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Dec 2, 2022
@mxschmitt
Copy link
Member Author

mxschmitt commented Dec 2, 2022

This is from @next and 4.9 so its persistent on both versions.


> playwright-internal@1.29.0-next tsc
> tsc -p .

node_modules/@types/node/globals.d.ts:114:13 - error TS2403: Subsequent variable declarations must have the same type.  Variable 'AbortSignal' must be of type '{ new (): AbortSignal
; prototype: AbortSignal; abort(reason?: any): AbortSignal; timeout(milliseconds: number): AbortSignal; }', but here has type '{ new (): AbortSignal; prototype: AbortSignal; }'.    
114 declare var AbortSignal: {
                ~~~~~~~~~~~

  node_modules/typescript/lib/lib.dom.d.ts:2071:13
    2071 declare var AbortSignal: {
                     ~~~~~~~~~~~
    'AbortSignal' was also declared here.

packages/playwright-core/src/server/chromium/crPage.ts:348:35 - error TS2345: Argument of type 'ElementHandle<T>' is not assignable to parameter of type 'ElementHandle<Node>'.
  Type 'Node' is not assignable to type 'T'.
    'Node' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Node'.

348     return this._sessionForHandle(handle)._adoptElementHandle<T>(handle, to);
                                      ~~~~~~

packages/playwright-core/src/server/chromium/crPage.ts:1205:12 - error TS2352: Conversion of type 'Promise<ElementHandle<Node>>' to type 'Promise<ElementHandle<T>>' may be a mistake
 because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.                                                        Type 'ElementHandle<Node>' is not comparable to type 'ElementHandle<T>'.
    The types returned by 'jsonValue()' are incompatible between these types.
      Type 'Promise<Node>' is not comparable to type 'Promise<T>'.
        Type 'Node' is not comparable to type 'T'.
          'Node' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Node'.

1205     return this._adoptBackendNodeId(nodeInfo.node.backendNodeId, to) as Promise<dom.ElementHandle<T>>;
                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

packages/playwright-core/src/server/dispatchers/elementHandlerDispatcher.ts:208:91 - error TS2345: Argument of type 'ElementHandle<Element>' is not assignable to parameter of type '
ElementHandle<Node>'.                                                                                                                                                                
208     return { elements: elements.map(e => ElementHandleDispatcher.from(this.parentScope(), e)) };
                                                                                              ~

packages/playwright-core/src/server/dispatchers/elementHandlerDispatcher.ts:224:80 - error TS2345: Argument of type 'ElementHandle<Element> | null' is not assignable to parameter of
 type 'ElementHandle<Node> | null'.                                                                                                                                                  
224     return { element: ElementHandleDispatcher.fromNullable(this.parentScope(), await this._elementHandle.waitForSelector(metadata, params.selector, params)) };
                                                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

packages/playwright-core/src/server/dispatchers/frameDispatcher.ts:87:80 - error TS2345: Argument of type 'ElementHandle<Element> | null' is not assignable to parameter of type 'Ele
mentHandle<Node> | null'.                                                                                                                                                            
87     return { element: ElementHandleDispatcher.fromNullable(this.parentScope(), await this._frame.waitForSelector(metadata, params.selector, params)) };
                                                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

packages/playwright-core/src/server/dispatchers/frameDispatcher.ts:103:80 - error TS2345: Argument of type 'ElementHandle<Element> | null' is not assignable to parameter of type 'El
ementHandle<Node> | null'.                                                                                                                                                           
103     return { element: ElementHandleDispatcher.fromNullable(this.parentScope(), await this._frame.querySelector(params.selector, params)) };
                                                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

packages/playwright-core/src/server/dispatchers/frameDispatcher.ts:108:91 - error TS2345: Argument of type 'ElementHandle<Element>' is not assignable to parameter of type 'ElementHa
ndle<Node>'.                                                                                                                                                                         
108     return { elements: elements.map(e => ElementHandleDispatcher.from(this.parentScope(), e)) };
                                                                                              ~

packages/playwright-core/src/server/dom.ts:140:12 - error TS2416: Property 'asElement' in type 'ElementHandle<T>' is not assignable to the same property in base type 'JSHandle<T>'.
  Type '() => ElementHandle<T> | null' is not assignable to type '() => ElementHandle<Node> | null'.
    Type 'ElementHandle<T> | null' is not assignable to type 'ElementHandle<Node> | null'.
      Type 'ElementHandle<T>' is not assignable to type 'ElementHandle<Node>'.
        Type 'Node' is not assignable to type 'T'.
          'Node' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Node'.

140   override asElement(): ElementHandle<T> | null {
               ~~~~~~~~~

packages/playwright-core/src/server/dom.ts:158:7 - error TS2322: Type 'SmartHandle<R>' is not assignable to type '"error:notconnected" | JSHandle<R>'.
  Type 'JSHandle<R> | ElementHandle<R>' is not assignable to type '"error:notconnected" | JSHandle<R>'.
    Type 'ElementHandle<R>' is not assignable to type '"error:notconnected" | JSHandle<R>'.
      Type 'ElementHandle<R>' is not assignable to type 'JSHandle<R>'.
        Type 'SmartHandle<R>' is not assignable to type 'JSHandle<R>'.
          Type 'JSHandle<R> | ElementHandle<R>' is not assignable to type 'JSHandle<R>'.
            Type 'ElementHandle<R>' is not assignable to type 'JSHandle<R>'.
              The types returned by 'asElement()' are incompatible between these types.
                Type 'ElementHandle<R> | null' is not assignable to type 'ElementHandle<Node> | null'.
                  Type 'ElementHandle<R>' is not assignable to type 'ElementHandle<Node>'.
                    Type 'Node' is not assignable to type 'R'.
                      'R' could be instantiated with an arbitrary type which could be unrelated to 'Node'.

158       return await utility.evaluateHandle(pageFunction, [await utility.injectedScript(), this, arg]);
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

packages/playwright-core/src/server/dom.ts:180:62 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'ElementHandle<Node>'.
  Type 'ElementHandle<T>' is not assignable to type 'ElementHandle<Node>'.
    The types returned by 'asElement()' are incompatible between these types.
      Type 'ElementHandle<T> | null' is not assignable to type 'ElementHandle<Node> | null'.

180     const frameId = await this._page._delegate.getOwnerFrame(this);
                                                                 ~~~~

packages/playwright-core/src/server/dom.ts:202:49 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'ElementHandle<Node>'.

202     return this._page._delegate.getContentFrame(this);
                                                    ~~~~

packages/playwright-core/src/server/dom.ts:257:66 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'ElementHandle<Node>'.

257     return await this._page._delegate.scrollRectIntoViewIfNeeded(this, rect);
                                                                     ~~~~

packages/playwright-core/src/server/dom.ts:309:44 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'ElementHandle<Node>'.

309       this._page._delegate.getContentQuads(this),
                                               ~~~~

packages/playwright-core/src/server/dom.ts:430:38 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'ElementHandle<Node>'.

430     await progress.beforeInputAction(this);
                                         ~~~~

packages/playwright-core/src/server/dom.ts:550:38 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'ElementHandle<Node>'.

550     await progress.beforeInputAction(this);
                                         ~~~~

packages/playwright-core/src/server/dom.ts:571:38 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'ElementHandle<Node>'.

571     await progress.beforeInputAction(this);
                                         ~~~~

packages/playwright-core/src/server/dom.ts:639:24 - error TS2352: Conversion of type 'ElementHandle<Node> | null' to type 'ElementHandle<HTMLInputElement>' may be a mistake because 
neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.                                                                 Type 'ElementHandle<Node>' is not comparable to type 'ElementHandle<HTMLInputElement>'.
    The types returned by 'jsonValue()' are incompatible between these types.
      Type 'Promise<Node>' is not comparable to type 'Promise<HTMLInputElement>'.
        Type 'Node' is not comparable to type 'HTMLInputElement'.

639     const retargeted = result.asElement() as ElementHandle<HTMLInputElement>;
                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

packages/playwright-core/src/server/dom.ts:640:38 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'ElementHandle<Node>'.

640     await progress.beforeInputAction(this);
                                         ~~~~

packages/playwright-core/src/server/dom.ts:679:38 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'ElementHandle<Node>'.

679     await progress.beforeInputAction(this);
                                         ~~~~

packages/playwright-core/src/server/dom.ts:700:38 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'ElementHandle<Node>'.

700     await progress.beforeInputAction(this);
                                         ~~~~

packages/playwright-core/src/server/dom.ts:745:48 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'ElementHandle<Node>'.

745     return this._page._delegate.getBoundingBox(this);
                                                   ~~~~

packages/playwright-core/src/server/dom.ts:751:75 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'ElementHandle<Node>'.

751         progress => this._page._screenshotter.screenshotElement(progress, this, options),
                                                                              ~~~~

packages/playwright-core/src/server/dom.ts:756:85 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'ElementHandle<Node> | undefined'.
  Type 'ElementHandle<T>' is not assignable to type 'ElementHandle<Node>'.
    Type 'this' is not assignable to type 'ElementHandle<Node>'.

756     const pair = await this._frame.resolveFrameForSelectorNoWait(selector, options, this);
                                                                                        ~~~~

packages/playwright-core/src/server/dom.ts:761:5 - error TS2322: Type 'ElementHandle<Element> | null' is not assignable to type 'ElementHandle<Node> | null'.
  Type 'ElementHandle<Element>' is not assignable to type 'ElementHandle<Node>'.

761     return this._page.selectors.query(frame, info, this._frame === frame ? this : undefined);
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

packages/playwright-core/src/server/dom.ts:761:52 - error TS2345: Argument of type 'this | undefined' is not assignable to parameter of type 'ElementHandle<Node> | undefined'.
  Type 'this' is not assignable to type 'ElementHandle<Node> | undefined'.

761     return this._page.selectors.query(frame, info, this._frame === frame ? this : undefined);
                                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

packages/playwright-core/src/server/dom.ts:765:80 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'ElementHandle<Node> | undefined'.

765     const pair = await this._frame.resolveFrameForSelectorNoWait(selector, {}, this);
                                                                                   ~~~~

packages/playwright-core/src/server/dom.ts:770:56 - error TS2345: Argument of type 'this | undefined' is not assignable to parameter of type 'ElementHandle<Node> | undefined'.

770     return this._page.selectors._queryAll(frame, info, this._frame === frame ? this : undefined, true /* adoptToMain */);
                                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

packages/playwright-core/src/server/dom.ts:774:88 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'ElementHandle<Node> | undefined'.

774     const pair = await this._frame.resolveFrameForSelectorNoWait(selector, { strict }, this);
                                                                                           ~~~~

packages/playwright-core/src/server/dom.ts:776:83 - error TS2345: Argument of type 'this | undefined' is not assignable to parameter of type 'ElementHandle<Node> | undefined'.

776     const handle = pair ? await this._page.selectors.query(pair.frame, pair.info, this._frame === pair.frame ? this : undefined) : null;
                                                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

packages/playwright-core/src/server/dom.ts:785:80 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'ElementHandle<Node> | undefined'.

785     const pair = await this._frame.resolveFrameForSelectorNoWait(selector, {}, this);
                                                                                   ~~~~

packages/playwright-core/src/server/dom.ts:790:88 - error TS2345: Argument of type 'this | undefined' is not assignable to parameter of type 'ElementHandle<Node> | undefined'.

790     const arrayHandle = await this._page.selectors._queryArrayInMainWorld(frame, info, this._frame === frame ? this : undefined);
                                                                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

packages/playwright-core/src/server/dom.ts:840:69 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'ElementHandle<Node> | undefined'.

840     return this._frame.waitForSelector(metadata, selector, options, this);
                                                                        ~~~~

packages/playwright-core/src/server/dom.ts:868:28 - error TS2352: Conversion of type 'ElementHandle<Node>' to type 'ElementHandle<Element>' may be a mistake because neither type suf
ficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.                                                                               
868       const frameElement = await frame.frameElement() as ElementHandle<Element>;
                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

packages/playwright-core/src/server/frames.ts:949:35 - error TS2345: Argument of type '() => Promise<dom.ElementHandle<HTMLElement>>' is not assignable to parameter of type '() => P
romise<ElementHandle<Node>>'.                                                                                                                                                          Type 'Promise<ElementHandle<HTMLElement>>' is not assignable to type 'Promise<ElementHandle<Node>>'.
    Type 'ElementHandle<HTMLElement>' is not assignable to type 'ElementHandle<Node>'.
      Type 'Node' is missing the following properties from type 'HTMLElement': accessKey, accessKeyLabel, autocapitalize, dir, and 234 more.

949     return this._raceWithCSPError(async () => {
                                      ~~~~~~~~~~~~~

packages/playwright-core/src/server/frames.ts:996:35 - error TS2345: Argument of type '() => Promise<dom.ElementHandle<HTMLElement>>' is not assignable to parameter of type '() => P
romise<ElementHandle<Node>>'.                                                                                                                                                          Type 'Promise<ElementHandle<HTMLElement>>' is not assignable to type 'Promise<ElementHandle<Node>>'.

996     return this._raceWithCSPError(async () => {
                                      ~~~~~~~~~~~~~

packages/playwright-core/src/server/frames.ts:1127:74 - error TS2345: Argument of type 'ElementHandle<Element>' is not assignable to parameter of type 'ElementHandle<Node>'.
  Type 'Node' is missing the following properties from type 'Element': attributes, classList, className, clientHeight, and 114 more.

1127       return await this._page._screenshotter.screenshotElement(progress, handle, options);
                                                                              ~~~~~~

packages/playwright-core/src/server/selectors.ts:84:56 - error TS2589: Type instantiation is excessively deep and possibly infinite.

84     const handle = await injectedScript.evaluateHandle((injected, { parsed, scope, strict }) => {
                                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

packages/playwright-core/src/server/selectors.ts:129:29 - error TS2352: Conversion of type 'ElementHandle<Node> | null' to type 'ElementHandle<Element>' may be a mistake because nei
ther type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.                                                                    Type 'ElementHandle<Node>' is not comparable to type 'ElementHandle<Element>'.
    The types returned by 'jsonValue()' are incompatible between these types.
      Type 'Promise<Node>' is not comparable to type 'Promise<Element>'.
        Type 'Node' is not comparable to type 'Element'.

129       const elementHandle = property.asElement() as dom.ElementHandle<Element>;
                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Found 39 errors in 7 files.

Errors  Files
     1  node_modules/@types/node/globals.d.ts:114
     2  packages/playwright-core/src/server/chromium/crPage.ts:348
     2  packages/playwright-core/src/server/dispatchers/elementHandlerDispatcher.ts:208
     3  packages/playwright-core/src/server/dispatchers/frameDispatcher.ts:87
    26  packages/playwright-core/src/server/dom.ts:140
     3  packages/playwright-core/src/server/frames.ts:949
     2  packages/playwright-core/src/server/selectors.ts:84

@ahejlsberg
Copy link
Member

The errors related to AboutSignal look to be because you need a newer version of the @types/node package.

The remaining errors are all related to type parameter variance for the ElementHandle<T> class in packages/playwright-core/src/server/dom.ts. It appears that TS 4.7.3 computes T to be bivariant (i.e. both co- and contra-variant), whereas later versions of the compiler computes T to be invariant (i.e. neither co- nor contra-variant). I'm not sure why this changed, but I'll research a bit more.

Meanwhile, a simple way to fix this is to add an explicit out variance annotation to ElementHandle<T> and then suppress the errors that result from validating the annotation:

// @ts-ignore-errors
export class ElementHandle<out T extends Node = Node> extends js.JSHandle<T> {
    // ...
}

@ahejlsberg
Copy link
Member

ahejlsberg commented Dec 3, 2022

Manually bisected the break to #50397.

@ahejlsberg
Copy link
Member

So, the specific change in #50397 that caused the break is the same I discuss here. Previously we didn't correctly analyze the full set of constraints of conditional types, and this weaker analysis always didn't hit upon the infinite recursion that can occur between the ElementHandle, Func1, and Unboxed types. I think your best cause of action is to simplify the relationship here. It's hard for me to suggest exact changes as I'm not really sure what the types are trying to accomplish.

@mxschmitt
Copy link
Member Author

Thanks! We were able to resolve it, so closing for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Investigation This issue needs a team member to investigate its status.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants