Skip to content

[🐛 Bug]: Overwrite command's original function type problem #14548

@dprevost-LMI

Description

@dprevost-LMI

Have you read the Contributing Guidelines on issues?

WebdriverIO Version

9.15.0

Node.js Version

18

Mode

Standalone Mode

Which capabilities are you using?

N/A

What happened?

The below code shows the originalFunction as (parameter) originalFunction: (...args: any[]) => (this: WebdriverIO.Element) => Promise<string> while it should (parameter) originalFunction: () => Promise<string>

browser.overwriteCommand(
  'getText',
  async function (this: WebdriverIO.Element, originalFunction) {
    // Error with `Type '(this: Element) => Promise<string>' is not assignable to type 'string'.ts(2322)`, while typeof text is string
    const text: string = await originalFunction();
    return text
  },
  true,
);

This is caused by the two types below, where origCommand is using (...args: any[]) =>, and because $ElementCommands[ElementKey] is missing OmitThisParameter

type OverwriteCommandFnScoped<ElementKey extends keyof $ElementCommands, BrowserKey extends keyof $BrowserCommands, IsElement extends boolean = false> = (this: IsElement extends true ? WebdriverIO.Element : WebdriverIO.Browser, origCommand: (...args: any[]) => IsElement extends true ? $ElementCommands[ElementKey] : $BrowserCommands[BrowserKey], ...args: any[]) => Promise<any>;
type OverwriteCommandFn<ElementKey extends keyof $ElementCommands, BrowserKey extends keyof $BrowserCommands, IsElement extends boolean = false> = (origCommand: (...args: any[]) => IsElement extends true ? $ElementCommands[ElementKey] : $BrowserCommands[BrowserKey], ...args: any[]) => Promise<any>;

When using the below types, the originalFunction is now correctly inferred

type OverwriteCommandFnScoped<ElementKey extends keyof $ElementCommands, BrowserKey extends keyof $BrowserCommands, IsElement extends boolean = false> = (this: IsElement extends true ? WebdriverIO.Element : WebdriverIO.Browser, origCommand: IsElement extends true ? OmitThisParameter<$ElementCommands[ElementKey]> : $BrowserCommands[BrowserKey], ...args: any[]) => Promise<any>;
type OverwriteCommandFn<ElementKey extends keyof $ElementCommands, BrowserKey extends keyof $BrowserCommands, IsElement extends boolean = false> = (origCommand: IsElement extends true ? OmitThisParameter<$ElementCommands[ElementKey]> : $BrowserCommands[BrowserKey], ...args: any[]) => Promise<any>;

We also encounter a similar issue when overriding the command in the browser.

PR is coming…

What is your expected behavior?

When overriding a command, the IDE should properly resolve the type of the original function so that I can call it properly and have the result of the function also correctly typed.

How to reproduce the bug.

Try the below snippet, and a type error will appear saying the text is not of type string but Promise<string>

browser.overwriteCommand(
  'getText',
  async function (this: WebdriverIO.Element, originalFunction) {
    // Error with `Type '(this: Element) => Promise<string>' is not assignable to type 'string'.ts(2322)`, while typeof text is string
    const text: string = await originalFunction();
    return text
  },
  true,
);

Relevant log output

Type '(this: Element) => Promise<string>' is not assignable to type 'string'.ts(2322)
 Error (TS2322)  | 

Type 
 is not assignable to type 
 .
const text: string

Code of Conduct

  • I agree to follow this project's Code of Conduct

Is there an existing issue for this?

  • I have searched the existing issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    Bug 🐛help wantedIssues that are free to take by anyone interested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions