Search code examples
javascripttypescriptcypress

Cypress error in Commands.ts (Argument of type '"login"' is not assignable to parameter of type 'keyof Chainable<any>)


I am trying to use commands.ts to implify repeating actions, like asking for email and password.

but when I try to use this, it gives me the rror for the login(Argument of type '"login"' is not assignable to parameter of type 'keyof Chainable)

`

Cypress.Commands.add("login", (email, password) => {
   some codes....
})

`

I didn't try anything else


Solution

  • NEW ANSWER

    create a file global.d.ts with

    namespace Cypress {
        interface Chainable {
            login(email:string, password:string): Chainable<void>;
        }
    }
    

    OLD ANSWER

    create a file index.ts on the same level as commands.ts

    put inside

    export {}
    declare global {
        namespace Cypress {
            interface Chainable {
                login(email:string, password:string): Chainable<void>;
            }
        }
    }
    

    enjoy

    UPDATE - WHY IT WORKS

    When we use Typescript everything needs an interface to be described. In your example, Cypress has its Chainable interface but you wish it to have a 'login' property too. With this code, you are saying that you want to extend 'Cypress.Chainable' to have a login property.

    Let me explain it to you with another real example

    interface String {
      myOwnChainableFunction: Function
    }
    
    String.prototype.myOwnChainableFunction = function (this: string){
    console.log(this)
    }
    
    'ciao'.myOwnChainableFunction();
    

    In this example, we are extending the String prototype to accept our own function in chain. In Javascript, we have just to attach it to the prototype but with .ts the Typescript checker pretends this property exists in the String interface, so we added it to the interface too.