diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index dde1a928b7..11aa72dd2d 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -492,6 +492,10 @@ declare namespace Cypress { } type CanReturnChainable = void | Chainable + type ThenReturn = + R extends void ? Chainable : + R extends R | undefined ? Chainable> : + Chainable /** * Chainable interface for non-array Subjects @@ -1751,12 +1755,24 @@ declare namespace Cypress { * @see https://on.cypress.io/then */ then(fn: (this: ObjectLike, currentSubject: Subject) => S): Chainable + /** + * Enables you to work with the subject yielded from the previous command / promise. + * + * @see https://on.cypress.io/then + */ + then(fn: (this: ObjectLike, currentSubject: Subject) => S): ThenReturn /** * Enables you to work with the subject yielded from the previous command / promise. * * @see https://on.cypress.io/then */ then(options: Partial, fn: (this: ObjectLike, currentSubject: Subject) => S): Chainable + /** + * Enables you to work with the subject yielded from the previous command / promise. + * + * @see https://on.cypress.io/then + */ + then(options: Partial, fn: (this: ObjectLike, currentSubject: Subject) => S): ThenReturn /** * Enables you to work with the subject yielded from the previous command. * diff --git a/cli/types/tests/cypress-tests.ts b/cli/types/tests/cypress-tests.ts index ccc8e1cba7..a116041136 100644 --- a/cli/types/tests/cypress-tests.ts +++ b/cli/types/tests/cypress-tests.ts @@ -179,6 +179,25 @@ cy.wrap(['bar', 'baz']) }) describe('then', () => { + // https://github.com/cypress-io/cypress/issues/5575 + it('should respect the return type of callback', () => { + // Expected type is verbose here because the function below matches 2 declarations. + // * then(fn: (this: ObjectLike, currentSubject: Subject) => S): Chainable + // * then(fn: (this: ObjectLike, currentSubject: Subject) => S): ThenReturn + // For our purpose, it doesn't matter. + const result = cy.get('foo').then(el => el.attr('foo')) + result // $ExpectType Chainable> | Chainable> + + const result2 = cy.get('foo').then(el => `${el}`) + result2 // $ExpectType Chainable + + const result3 = cy.get('foo').then({ timeout: 1234 }, el => el.attr('foo')) + result3 // $ExpectType Chainable> | Chainable> + + const result4 = cy.get('foo').then({ timeout: 1234 }, el => `${el}`) + result4 // $ExpectType Chainable + }) + it('should have the correct type signature', () => { cy.wrap({ foo: 'bar' }) .then(s => {