Cypress ships with official type declarations for TypeScript. This allows you to write your tests in TypeScript. All that is required is a little bit of configuration.
Transpiling TypeScript test files
Just as you would when writing TypeScript files in your project, you will have to handle transpiling your TypeScript test files. Cypress exposes a file:preprocessor
event you can use to customize how your test code is transpiled and sent to the browser.
Examples
Set up your dev environment
Please refer to your code editor in TypeScript’s Editor Support doc and follow the instructions for your IDE to get TypeScript support and intelligent code completion configured in your developer environment before continuing. TypeScript support is built in for Visual Studio Code, Visual Studio, and WebStorm - all other editors require extra setup.
Configure tsconfig.json
We recommend the following configuration in a tsconfig.json
inside your cypress
folder.
{ "compilerOptions": { "strict": true, "baseUrl": "../node_modules", "target": "es5", "lib": ["es5", "dom"], "types": ["cypress"] }, "include": [ "**/*.ts" ] }
The "types"
will tell the TypeScript compiler to only include type definitions from Cypress. This will address instances where the project also uses @types/chai
or @types/jquery
. Since Chai and jQuery are namespaces (globals), incompatible versions will cause the package manager (yarn
or npm
) to nest and include multiple definitions and cause conflicts.
You can find an example of Jest and Cypress installed in the same project using a separate
tsconfig.json
file in the cypress-io/cypress-and-jest-typescript-example repo.
Types for custom commands
When adding custom commands to the cy
object, you can manually add their types to avoid TypeScript errors.
For example if you add the command cy.dataCy
into your supportFile
like this:
// cypress/support/index.js Cypress.Commands.add('dataCy', (value) => { return cy.get(`[data-cy=${value}]`) })
Then you can add the dataCy
command to the global Cypress Chainable interface (so called because commands are chained together) by creating a new TypeScript definitions file beside your supportFile
, in this case at cypress/support/index.d.ts
.
// in cypress/support/index.d.ts // load type definitions that come with Cypress module /// <reference types="cypress" /> declare namespace Cypress { interface Chainable { /** * Custom command to select DOM element by data-cy attribute. * @example cy.dataCy('greeting') */ dataCy(value: string): Chainable<Element> } }
A nice detailed JSDoc comment above the method type will be really appreciated by any users of your custom command.
If your specs files are in TypeScript, you should include the TypeScript definition file, cypress/support/index.d.ts
, with the rest of the source files.
Even if your project is JavaScript only, the JavaScript specs can know about the new command by referencing the file using the special tripple slash reference path
comment.
// from your cypress/integration/spec.js /// <reference path="../support/index.d.ts" /> it('works', () => { cy.visit('/') // IntelliSense and TS compiler should // not complain about unknown method cy.dataCy('greeting') })
Examples:
- See Adding Custom Commands example recipe.
- You can find a simple example with custom commands written in TypeScript in omerose/cypress-support repo.
- Example project cypress-example-todomvc custom commands uses custom commands to avoid boilerplate code.
Types for custom assertions
If you extend Cypress assertions, you can extend the assertion types to make the TypeScript compiler understand the new methods. See the Recipe: Adding Chai Assertions for instructions.
Additional information
See the excellent advice on setting Cypress using TypeScript in the TypeScript Deep Dive e-book by Basarat Syed. Take a look at this video Basarat has recorded and the accompanying repo basarat/cypress-ts.
We have published a utility npm module, add-typescript-to-cypress, that sets TypeScript test transpilation for you with a single command.