-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
feat: infer argument types in command implementations #17496
feat: infer argument types in command implementations #17496
Conversation
`Cypress.Commands.add` now only accepts commands that have been declared, and the implementation is now properly typed.
Thanks for taking the time to open a PR!
|
@remcohaszing Can you describe the problem that you were encountering before that requires this PR? It looks like this is making it so that types are required for custom commands. We're concerned this will cause issues for users who are importing custom commands from plugins that are not typed and have not defined the custom command themselves. We don't want them to have an error for a custom command they didn't write. Is this accurate? |
This is already the case and TypeScript users such as myself love this. Cypress already has a dedicated section in the documentation for this. This basically means that if someone wishes to use for example This pull request builds on the existing functionality by adding type safety for the implementation of commands, if they are written in TypeScript. For example, let’s say a user has declared the following command: namespace Cypress {
export interface Chainable {
login: (redirect: string) => void;
}
} When using the following implementation in Cypress 8.0.0, the type of Cypress.Commands.add('login', (redirect) => {
cy.visit('/en/login', { qs: { redirect } });
cy.get('#email').type(Cypress.env('ACCOUNT_EMAIL'));
cy.get('#password').type(Cypress.env('ACCOUNT_PASSWORD'));
cy.get('[type="submit"]').click();
cy.location('pathname').should('equal', redirect);
}); One could add a type annotation, but it doesn’t even have to match the declared type Cypress.Commands.add('login', (redirect: boolean /* obviously wrong */) => {
cy.visit('/en/login', { qs: { redirect } });
cy.get('#email').type(Cypress.env('ACCOUNT_EMAIL'));
cy.get('#password').type(Cypress.env('ACCOUNT_PASSWORD'));
cy.get('[type="submit"]').click();
cy.location('pathname').should('equal', redirect);
}); With these changes, the type of the |
@remcohaszing Would this be a breaking change for users that have not defined types in custom commands previously? So it will error in that case? |
This would not be a breaking change. Currently TypeScript users have to declare the custom commands in order to use them. This change will identify commands that have been implemented, but are undeclared and therefor unused. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a nice enhancement 👍 Thanks for the PR!
I agree this is non-breaking.
Looks like we need to consider this breaking after all. See this type check failure when we test against the kitchensink. Adding commands in That's okay though, we can target this at the next major release (9.0). |
I disagree. The situation for type checking with
The proper solution would be to define these types in a TypeScript file, even if the rest is written in JavaScript with the I found the file here while typing this issue. On line 33 the command is used and the TypeScript error is suppressed because it’s undeclared. |
I agree, but if an upgrade to Cypress causes a user to have to change their code in order for their CI workflows to succeed, then it's a breaking change. That's the case here. The kitchensink needs those types defined in order for the type checking to pass with these changes. There could be other users in the same situation. It's not a big deal. This will still get released, it will just have to wait a little while longer for the 9.0 release. |
I agree with this.
I don’t agree with this though. The kitchensink already has a type error, but it’s suppressed. If the suppressed issue is resolved in the kitchensink, then these changes will work. That having said I can wait for Cypress 9. I just prefer to have this additional type safety rather sooner than later. |
It will be inferred soon. cypress-io/cypress#17496
Released in This comment thread has been locked. If you are still experiencing this issue after upgrading to |
Cypress.Commands.add
now only accepts commands that have been declared, andthe implementation is now properly typed.
User facing changelog
Custom command implementations are now typed based on the declared custom chainables.
Additional details
This provides type safety when implementing commands.
How has the user experience changed?
Given:
Before:
After:
PR Tasks
type definitions
?