Cypress: Type 'Promise<any>' is not assignable to type 'CanReturnChainable' in Cypress

Created on 25 Jun 2020  路  8Comments  路  Source: cypress-io/cypress

Current behavior:

Having updated from Cypress 4.8, TypeScript will now not compile my support code. #435 was not insightful.

Desired behavior:

Compile my TypeScript. Either I'm doing something wrong or there is a bug.

Test code to reproduce

Cypress.Commands.overwrite(command, (originalFn, ...args) => {
  const origVal = originalFn(...args);
  return new Promise(resolve => {
    setTimeout(() => resolve(origVal), 1000);
  });
});

It fails similarly with Cypress.Promise as well. I'd like to avoid cy.wrap() unless necessary.

Versions

Cypress 4.9.0
macOS 10.15.5
Chrome 83

typescript regression v4.9.0

Most helpful comment

@jennifer-shehane I'm seeing similar behavior.

  • Yes, it's code added to support/index.ts
  • It's the compiler that complains. Weirdly enough the tests still run.
  • No preprocessor in plugins
  • Tsconfig file below
Cypress.Commands.add(
  "createReview",
  (payload: Partial<CreateReviewPayload>) => {
    const review = cleanObject<CreateReviewPayload>({
      title: payload.title || `[cy-test]`,
      description: "This is a review created for test purposes",
      tagIds: [],
      industryId: "__no_industry",
      type: "self-review",
      accountId: testAccountId,
      ...payload,
    });

    return functions
      .httpsCallable("createReview")(review)
      .then((result) => {
        const reviewId = result.data.reviewId as string;
        return firestore
          .collection("reviews")
          .doc(reviewId)
          .get()
          .then((snap) => ({
            id: reviewId,
            data: snap.data() as Review,
          }));
      });
  },
);

Error:

Argument of type '(payload: Partial<CreateReviewPayload>) => Promise<{ id: string; data: Review; }>' is not assignable to parameter of type '(...args: any[]) => CanReturnChainable'.
  Type 'Promise<{ id: string; data: Review; }>' is not assignable to type 'CanReturnChainable'.
    Type 'Promise<{ id: string; data: Review; }>' is missing the following properties from type 'Chainable<any>': and, as, blur, check, and 89 more.ts(2345)
{
  "compilerOptions": {
    "esModuleInterop": true,
    "jsx": "preserve",
    "lib": ["dom", "esnext"],
    "types": ["cypress", "node"],
    "module": "esnext",
    "moduleResolution": "node",
    "noEmit": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "preserveConstEnums": true,
    "removeComments": false,
    "skipLibCheck": true,
    "checkJs": false,
    "sourceMap": true,
    "strict": true,
    "target": "es2018",
    "allowJs": false,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "baseUrl": ".",
    "paths": {
      "/*": ["./src/*"]
    }
  }
}

For me this issue also started when upgrading from 4.8 to 4.9

All 8 comments

@stevenvachon Hey, can you provide some more info?

  • You're adding this code to a support/index.ts file?
  • How are you running your tests? (cypress open, cypress run)?
  • Do you have any preprocessors in your plugins?
  • Do you have a tsconfig file defind?
  • What is the error you are seeing?

I can't recreate this just adding this code to a support/index.ts file as you've described.

@jennifer-shehane I'm seeing similar behavior.

  • Yes, it's code added to support/index.ts
  • It's the compiler that complains. Weirdly enough the tests still run.
  • No preprocessor in plugins
  • Tsconfig file below
Cypress.Commands.add(
  "createReview",
  (payload: Partial<CreateReviewPayload>) => {
    const review = cleanObject<CreateReviewPayload>({
      title: payload.title || `[cy-test]`,
      description: "This is a review created for test purposes",
      tagIds: [],
      industryId: "__no_industry",
      type: "self-review",
      accountId: testAccountId,
      ...payload,
    });

    return functions
      .httpsCallable("createReview")(review)
      .then((result) => {
        const reviewId = result.data.reviewId as string;
        return firestore
          .collection("reviews")
          .doc(reviewId)
          .get()
          .then((snap) => ({
            id: reviewId,
            data: snap.data() as Review,
          }));
      });
  },
);

Error:

Argument of type '(payload: Partial<CreateReviewPayload>) => Promise<{ id: string; data: Review; }>' is not assignable to parameter of type '(...args: any[]) => CanReturnChainable'.
  Type 'Promise<{ id: string; data: Review; }>' is not assignable to type 'CanReturnChainable'.
    Type 'Promise<{ id: string; data: Review; }>' is missing the following properties from type 'Chainable<any>': and, as, blur, check, and 89 more.ts(2345)
{
  "compilerOptions": {
    "esModuleInterop": true,
    "jsx": "preserve",
    "lib": ["dom", "esnext"],
    "types": ["cypress", "node"],
    "module": "esnext",
    "moduleResolution": "node",
    "noEmit": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "preserveConstEnums": true,
    "removeComments": false,
    "skipLibCheck": true,
    "checkJs": false,
    "sourceMap": true,
    "strict": true,
    "target": "es2018",
    "allowJs": false,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "baseUrl": ".",
    "paths": {
      "/*": ["./src/*"]
    }
  }
}

For me this issue also started when upgrading from 4.8 to 4.9

@jennifer-shehane @0x80 I faced the same situation here, but with MailSlurp service:
// command.ts

import { MailSlurp } from 'mailslurp-client';

const getMailSlurpInstance = (apiKey: string) => {
  return new MailSlurp({ apiKey });
};

Cypress.Commands.add('createInbox', (apiKey: string) => {
  return getMailSlurpInstance(apiKey).createInbox();
});

This expected type from the command CanReturnChainable it is more a blocker than a helper in my case, just downgraded to version 4.8.0 as a workaround from now.

This issue also appears in 5.0.0

Confirmed. Trying to find the fix.

I worked around it by returning my promise prefixed with cy.window().then(() => myAsyncFunction()). I'm not using the window result but the return value will therefor get the chainable type.

The code for this is done in cypress-io/cypress#8501, but has yet to be released.
We'll update this issue and reference the changelog when it's released.

Released in 5.2.0.

This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v5.2.0, please open a new issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

brian-mann picture brian-mann  路  3Comments

carloscheddar picture carloscheddar  路  3Comments

simonhaenisch picture simonhaenisch  路  3Comments

rbung picture rbung  路  3Comments

dkreft picture dkreft  路  3Comments