Q26 of 38 · TypeScript
How do you add type definitions for a custom Cypress command in TypeScript?
Short answer
Short answer: Implement the command in a `commands.ts` file, then extend the `Cypress.Chainable` interface in a `.d.ts` declaration file (or in the same file with a `declare global` block) to register the new method with its typed parameters and return type.
Detail
Cypress uses declaration merging — you extend the Cypress.Chainable<Subject> interface to add your command's type signature to every cy. call.
Step 1 — Implement the command:
Cypress.Commands.add("login", (email: string, password: string) => {
cy.request("POST", "/api/login", { email, password })
.its("body.token").as("authToken");
});
Step 2 — Declare the type:
In a .d.ts file or with declare global:
declare global {
namespace Cypress {
interface Chainable {
login(email: string, password: string): Chainable<void>;
}
}
}
Step 3 — Include the declaration: Ensure the .d.ts file is included in your tsconfig.json's include array, or place it in a folder TypeScript already scans.
Overloads: Custom commands can have multiple overload signatures — declare them as multiple Chainable method signatures with different parameter types.
Subject typing: The generic Chainable<Subject> parameter represents the yielded subject. If your command yields an element, return Chainable<JQuery<HTMLElement>>.
// EXAMPLE
// support/commands.ts
Cypress.Commands.add("login", (email: string, password: string) => {
cy.request({
method: "POST",
url: "/api/auth/login",
body: { email, password },
}).then(({ body }) => {
window.localStorage.setItem("token", body.token);
});
});
Cypress.Commands.add("dataCy", (selector: string) => {
return cy.get(`[data-cy="${selector}"]`);
});
// support/commands.d.ts (or index.d.ts)
export {}; // make it a module
declare global {
namespace Cypress {
interface Chainable {
/** Log in via API and set token in localStorage */
login(email: string, password: string): Chainable<void>;
/** Select element by data-cy attribute */
dataCy(selector: string): Chainable<JQuery<HTMLElement>>;
}
}
}
// tsconfig.json — include the declaration
{
"include": ["cypress/**/*.ts", "cypress/**/*.d.ts"]
}