Cypress: Cannot pick up typings for Cypress with the Typescript recipe

Created on 5 Jan 2018  ·  40Comments  ·  Source: cypress-io/cypress

Current behavior:

Cypress ships with bundled typings but the compiler cannot pick up the typings for Cypress and fails on encountering acy call.

Desired behavior:

Typescript compiler can pick up the typings and test files compile successfully.

How to reproduce:

  1. Setup a vanilla cypress setup
  2. Use the provided typescript recipe
  3. Write an example spec file like:
    ts describe('Example', function () { it('Example task', function () { cy.visit('http://example.com'); });
  4. Observe the compiler failing on cy

Test code:

See above

Additional Info (images, stack traces, etc)

./cypress/integration/REDACTED.spec.ts
[tsl] ERROR in REDACTED(3, 5)
      TS2304: Cannot find name 'cy'.
  • Operating System: MacOS High Sierra 10.13.2
  • Cypress Version: 1.4.1 (both package and binary)
  • Browser Version: 63.0.3239.132 (Official Build) (64-bit)
typescript question

Most helpful comment

@ashnur I've noticed sometimes the Typescript server needs to be restarted (cache invalidation issue). You can do this by either from the command palette Cmd/Ctrl+Shift+P and type Restart Typescript server or restart VS Code.

All 40 comments

Does the tsconfig include Cypress?

I have a tsconfig.json file in projectRoot/cypress/tsconfig.json as the example shows:

{
  "extends": "../tsconfig.json",
  "include": [
    "integration/*.ts",
    "support/*.ts",
    "../node_modules/cypress"
  ]
}

Is this typescript compiler or typescript linter?

Sent from my iPhone

On Jan 6, 2018, at 21:37, Attila Oláh notifications@github.com wrote:

I have a tsconfig.json file in projectRoot/cypress/tsconfig.json as the example shows:

{
"extends": "../tsconfig.json",
"include": [
"integration/.ts",
"support/
.ts",
"../node_modules/cypress"
]
}

You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

Both, VS code doesn't see the typings neither the compiler.

Hello,

I have the same kind of issue with Cypress and typescript. I followed what is explained here : https://www.cypress.io/blog/2017/12/11/an-alternative-to-protractor-for-angular-projects/#Scaffolding-a-project in my own project.
When running the test it fails with errors like those :

[...]/node_modules/cypress/types/index.d.ts
error TS2503: Cannot find namespace '_'.
[...]/node_modules/cypress/types/index.d.ts
error TS2304: Cannot find name 'JQuery'.

What am I missing ?
Thanks in advance

I wonder if TypeScript compiler does not find types for some reason. Like it does not see the included files referenced from non-root tsconfig.json for example? I don't know why that would be the case though.

  "include": [
    "../../node_modules/cypress",
    "cypress/*/*.ts"
  ]

same situation with vscode.

@bahmutov aren't your files in nested directories? If that's the case, change this in include property cypress/**/*.ts.

Any resolution? Experiencing the same issue here (and it has nothing to do with nested paths, tried the solution above)

We have this other issue that explains this... https://github.com/cypress-io/cypress/issues/1236

One thing that helps a lot for JS and TS specs is adding a comment to manually tell where the cypress types are coming from

/// <reference types="cypress" />

At least in VSCode the types start working, here is IntelliSense when hovering over cy.visit

intellisense-vscode

Try adding "types": ["cypress"] to the tsconfig.json file under the Cypress directory. That worked for me. That should do the same thing as the reference directive @bahmutov suggested, but for all TS files.

Finally got it to work with tsconfig.json like in https://github.com/cypress-io/cypress-example-recipes/tree/master/examples/preprocessors__typescript-webpack:

  "include": [
    "node_modules/cypress/types/index.d.ts",
    "node_modules/cypress/types/blob-util.d.ts",
    "node_modules/cypress/types/minimatch.d.ts",
    "node_modules/cypress/types/bluebird.d.ts",
    "cypress/**/*.ts"
  ]

However, if i do something like

  "include": [
    "node_modules/cypress/types/\*",
    "cypress/**/*.ts"
  ]

"node_modules/cypress/types/chai.d.ts" is also included and those definitions clash with the chai typings that are installed in node_modules/@types/ due to cypress dependencies in its package.json:

@types/chai/index.d.ts
(39,17) Duplicate identifier 'Operator'... bug?

@guetar A duplicate identifier like the is probably because you use Chai in your project. Cypress is currently using @types/[email protected]. If your project also uses @types/chai, but your version is incompatible with 4.0.8, your package manager (yarn or npm) will nest @types/chai under node_modules/cypress/node_modules - meaning you'll have 2 versions of chai type definitions. Since it is a namespace (global), TypeScript will throw a duplicate identifier.

One of the solutions that worked well for me in this case (duplicate definitions) was to have a tsconfig.json inside the cypress folder that looked like this:

{
  "extends": "../tsconfig",
  "compilerOptions": {
    "baseUrl": "../node_modules",
    "target": "es5",
    "types": ["cypress"],
  },
  "include": [
    "**/*.ts"
  ]
}

The extends is useful if you have a base tsconfig.json. Without it, you'll have to determine your own compiler options for the cypress directory.

A nuclear option would be to add skipLibCheck set to true which will disable TypeScript type checking inside lib files.

Adding /// <reference types="cypress" /> in top of every file solves the issue, playing around with tsconfig does not. For me maybe an extension messes up something.

I'm just dropping into this thread, but - would it not be helpful to keep @types/cypress npm package published as this is the preferred way to handle types in TypeScript? It could help people who are struggling with hooking up the types from within Cypress' install - I know it should be unnecessary for most though.

No, having to install separate @types/cypress would be a huge pain. Most packages that have types just include them (like we do).

Well, it seems that Vue.js does the same, includes types in core, but their configuration does not require defining types, baseUrl, includes. So, I'm just wondering what the discrepancy is? Why is ours so much more difficult to set up?

because for us the main things that cause problems

  • global reference to cy which requires configuration (vs import vue from 'vue')
  • conflicts with other global test things like Jest that also use expect and stuff like that :(

Yeah, I was just getting to this conclusion in my reading. :/ Thanks.

There are new docs explaining how to configure TypeScript support. We would love any feedback on whether our recommended setup solves the issues laid out in this issue. https://on.cypress.io/typescript-support

There is also a new issue open proposing more "native" support of TypeScript (less config) if anyone has suggestions they'd like to add there: https://github.com/cypress-io/cypress/issues/1859

I am closing this issue, but please feel free to comment here again with any feedback/confusion!

@jennifer-shehane - I'm running into an issue with code completion / Intellisense (VS Code) that feels akin to what is being described here. Per your recommendation, I'm adding a comment in the hopes that you'll see it - especially since I am following right along with the docs (as you suggested :)

Environment

  • macOS High Sierra (10.13.6)
  • VS Code (Insider, 1.27.0-insider, 2018-09-03T09:01:07.649Z)
  • Cypress 3.1.0

Install

  1. Log in to macOS (user account)
  2. Open "terminal.app"
  3. brew install node
  4. npm install -g cypress
  5. npm install -g eslint
  6. npm install -g eslint-plugin-chai-friendly
  7. npm install -g eslint-plugin-cypress
  8. npm install -g jshint

RESULT

My-User:~ myuser$ ll -a /usr/local/lib/node_modules/
total 0
drwxr-xr-x 8 myuser admin 256B Sep 5 11:04 .
drwxrwxr-x 18 myuser admin 576B Sep 4 14:40 ..
drwxr-xr-x 9 myuser admin 288B Sep 4 14:52 cypress
drwxr-xr-x 11 myuser admin 352B Sep 5 10:54 eslint
drwxr-xr-x 7 myuser admin 224B Sep 5 11:04 eslint-plugin-chai-friendly
drwxr-xr-x 7 myuser admin 224B Sep 5 10:58 eslint-plugin-cypress
drwxr-xr-x 11 myuser admin 352B Sep 4 14:41 jshint
drwxr-xr-x 24 myuser admin 768B Sep 4 14:40 npm

Setup - Cypress

  1. Open "terminal.app"
  2. mkdir /users/myuser/_CYPRESS
  3. cd /users/myuser/_CYPRESS
  4. npx cypress open

RESULT (~/_CYPRESS)

My-User:~ myuser$ ll -a /users/myuser/_CYPRESS/
total 24
drwxr-xr-x 7 myuser staff 224B Sep 5 11:00 .
drwxr-xr-x+ 67 myuser staff 2.1K Sep 4 11:58 ..
drwxr-xr-x 8 myuser staff 256B Sep 5 10:56 cypress
-rw-r--r--@ 1 myuser staff 3B Sep 4 14:53 cypress.json

RESULT (~/_CYPRESS/cypress)

My-User:~ myuser $ ll -a /users/myuser/_CYPRESS/cypress
total 16
drwxr-xr-x 8 myuser staff 256B Sep 5 10:56 .
drwxr-xr-x 7 myuser staff 224B Sep 5 11:00 ..
drwxr-xr-x 3 myuser staff 96B Sep 4 14:53 fixtures
drwxr-xr-x 5 myuser staff 160B Sep 4 14:56 integration
drwxr-xr-x 3 myuser staff 96B Sep 4 14:53 plugins
drwxr-xr-x 5 myuser staff 160B Sep 4 14:56 support

Setup - tsconfig.json

  1. Open "terminal.app"
  2. nano /users/myuser/_CYPRESS/cypress/tsconfig.json
  3. Add the following to the file, then save:
{
  "compilerOptions": {
    "allowJs": true,
    "baseUrl": "../node_modules",
    "types": [
      "cypress"
    ]
  },
  "include": [
    "**/*.*"
  ]
}

Setup - .eslintrc.json

  1. Open "terminal.app"
  2. nano /users/myuser/_CYPRESS/cypress/.eslintrc.json
  3. Add the following to the file, then save:
{
  "plugins": [
    "cypress",
    "chai-friendly"
  ],
  "env": {
    "cypress/globals": true
  },
  "rules": {
    "no-unused-expressions": 0,
    "chai-friendly/no-unused-expressions": 2
  }
}

VS Code

  1. Launch VS Code
  2. Open /users/myuser/_CYPRESS/cypress/integration/examples/actions.spec.js

ISSUES

  • Type "cy.get"
    -- note that code completion / Intellisense is not triggered
  • Display VS Code's "Output" pane (View -> Output | shift + command + U)
    -- Note the following message is displayed:
    > Cannot find type definition file for 'cypress'.

@Knaledge is there a reason you install Cypress globally? Do the types work when installing locally?

@Knaledge I confirmed that this is happening when Cypress is installed globally, see https://github.com/cypress-io/cypress/issues/2438

@bahmutov As mentioned in Gitter, I sincerely appreciate the time you've spent having a look at this (especially with an artifact of a separate "story" / issue).

For my particular circumstance, there's no "project" at the moment - I simply have Cypress installed on my Mac (via npm) and just write my tests in VS Code, then export to the development VM / commit to repo when they are more or less reviewed/tested/ready. The target application does not use node, so a lot of what I'm doing is: API testing, UI sanity, and general feature verification.

All that said, I could also just install Cypress "locally" (in a "project" folder - like _CYPRESS). I actually did have that set up - but I was still not getting Intellisense (code completion) working in VS Code.

When I started over, I went back a global install as it felt cleaner and made more sense.

All that said - what _do_ I put into tsconfig.json ? It seems there are a lot of assumptions in the docs that Cypress is installed locally (i.e. not globally installed) - but it's not clear when that matters. Just an observation, not a knock (as I absolutely love your docs).

Happens with local install too. Interesting how such a minor thing can go on for many many months without getting resolved.

@ashnur We have not been able to replicate issues with Intellisense/tsconfig when Cypress is installed locally using VSCode. Could you provide the details and steps to replicate your issue please?

For some miraculous reason it has resolved itself and as I am not really in the mood if debugging something as big as Cypress, so I was very careful not to even shut down my machine, in case it stops working again.
May I ask though, on this note, if you believe that the comment /// <reference types="cypress" /> is necessary for this feature to fully work? I included it, but it's kind of an eyesore, something that is only there because someone on the interwebs claimed this might help :)

It shouldn't be necessary if you've set up everything the way the TypeScript Doc laid out.

@ashnur I've noticed sometimes the Typescript server needs to be restarted (cache invalidation issue). You can do this by either from the command palette Cmd/Ctrl+Shift+P and type Restart Typescript server or restart VS Code.

@guetar A duplicate identifier like the is probably because you use Chai in your project. Cypress is currently using @types/[email protected]. If your project also uses @types/chai, but your version is incompatible with 4.0.8, your package manager (yarn or npm) will nest @types/chai under node_modules/cypress/node_modules - meaning you'll have 2 versions of chai type definitions. Since it is a namespace (global), TypeScript will throw a duplicate identifier.

One of the solutions that worked well for me in this case (duplicate definitions) was to have a tsconfig.json inside the cypress folder that looked like this:

{
  "extends": "../tsconfig",
  "compilerOptions": {
    "baseUrl": "../node_modules",
    "target": "es5",
    "types": ["cypress"],
  },
  "include": [
    "**/*.ts"
  ]
}

The extends is useful if you have a base tsconfig.json. Without it, you'll have to determine your own compiler options for the cypress directory.

A nuclear option would be to add skipLibCheck set to true which will disable TypeScript type checking inside lib files.

This worked for me! Thank you!

Just a quick note for Atom: the second cypress/tsconfig.json with "types": ["cypress"] and "extends": "../tsconfig", was only recognized after restart.

Adding /// <reference types="cypress" /> in top of every file solves the issue, playing around with tsconfig does not. For me maybe an extension messes up something.

This was my issue- prettier is formatting that to // / <reference types="cypress" /> 😭

Here is what I use and I do not have to add /// <reference types="cypress" /> at the top of every file.

I have my custom typings under <projectroot>/cypress/support/index.d.ts

/// <reference types="cypress" />

declare namespace Cypress {
  interface Chainable<Subject> {
    getByDataTest(tag: string): Chainable<any>
  }
}

And my <projectroot>/cypress/tsconfig.json looks like

{
  "compilerOptions": {
    "strict": true,
    "baseUrl": "../node_modules",
    "target": "es5",
    "lib": ["es5", "dom"],
    "types": ["cypress"],
    "typeRoots": ["./support"]
  },
  "include": ["**/*.ts"]
}

And TypeScript is finally happy

describe('when I want to select by data test tag', () => {
  it('should select by data test tag', () => {
    cy.getByDataTest('yolo').should('exist')
  });
});

@GentryRiggen added the reference works. sadly a bit of additional coding.

I finally figured out that, for some reason, awesome-typescript-loader is incompatible with the cypress-webpack-preprocessor-plugin, and throws these errors. Switching to ts-loader fixed things for me.

I had the same error. Adding the following to my tsconfig.json solved the problem for me.

    "types": [
      "./support/index"
    ]

Adding /// <reference types="cypress" /> in top of every file solves the issue, playing around with tsconfig does not. For me maybe an extension messes up something.

Simply adding /// <reference types="cypress" /> once in cypress/support/index.js made the tick for me.

After trying all the solutions above, I just had to mix the two most useful comments for me by @NicholasBoll :

https://github.com/cypress-io/cypress/issues/1152#issuecomment-374930065
https://github.com/cypress-io/cypress/issues/1152#issuecomment-435560901

...and it works as it should. : ) 👍

I had the same error. Adding the following to my tsconfig.json solved the problem for me.

    "types": [
      "./support/index"
    ]

What is in the support/index file?

Was this page helpful?
0 / 5 - 0 ratings