---
id: app/tooling/typescript-support
title: TypeScript Support in Cypress
description: >-
  Learn how to set up TypeScript in Cypress, configure TypeScript for custom
  commands, assertions, and plugins and more
section: app
source_path: docs/app/tooling/typescript-support.mdx
version: 6a908a532b1fca4ed18538a4c1c5a9bc7f24f403
updated_at: '2026-05-01T19:25:18.656Z'
---
# TypeScript Support

##### What you'll learn

*   How to set up TypeScript in Cypress
*   How to configure TypeScript for custom commands, assertions, and plugins
*   How to use TypeScript with Cypress component testing
*   How to avoid clashing types with Jest
*   How to set up your development environment for TypeScript

Cypress ships with [official type declarations](https://github.com/cypress-io/cypress/tree/develop/cli/types) for [TypeScript](https://www.typescriptlang.org/). This allows you to write your tests in TypeScript.

## Get Started

### Install TypeScript

To use TypeScript with Cypress, you will need TypeScript 5.x or TypeScript 6.x. If you do not already have TypeScript installed as a part of your framework, you will need to install it:

*   npm
*   yarn

```
npm install typescript --save-dev
```

```
yarn add typescript --dev
```

### Configure tsconfig.json

We recommend creating a [`tsconfig.json`](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html) inside your [`cypress` folder](/llm/markdown/app/core-concepts/writing-and-organizing-tests.md#Folder-structure) with the following configuration:

tsconfig.json

```
{  "compilerOptions": {    "target": "es6",    "lib": ["es6", "dom"],    "sourceMap": true,    "types": ["cypress", "node"]  },  "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](/llm/markdown/app/references/bundled-libraries.md#Chai) and [jQuery](/llm/markdown/app/references/bundled-libraries.md#Other-Library-Utilities) are namespaces (globals), incompatible versions will cause the package manager (`yarn` or `npm`) to nest and include multiple definitions and cause conflicts.

You may have to restart your IDE's TypeScript server if the setup above does not appear to work. For example:

VS Code (within a .ts or .js file):

*   Open the command palette (Mac: `cmd+shift+p`, Windows: `ctrl+shift+p`)
*   Type "restart ts" and select the "TypeScript: Restart TS server." option

If that does not work, try restarting the IDE.

### Processing your Cypress configuration and plugins

Under the hood, Cypress uses [tsx](https://tsx.is/) to parse and run the `cypress.config.ts` file.

This allows Cypress to run your TypeScript configuration inside the Cypress runtime without being bound to limitations of Node or other loaders.

## Extending TypeScript Support

### Types for Custom Commands

When adding [custom commands](/llm/markdown/api/cypress-api/custom-commands.md) 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](/llm/markdown/app/references/configuration.md#Testing-Type-Specific-Options) like this:

```
// cypress/support/index.tsCypress.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).

```
// cypress/support/index.tsdeclare global {  namespace Cypress {    interface Chainable {      /**       * Custom command to select DOM element by data-cy attribute.       * @example cy.dataCy('greeting')       */      dataCy(value: string): Chainable<JQuery<HTMLElement>>    }  }}
```

A nice detailed JSDoc comment above the method type will be really appreciated by any users of your custom command.

Types of all the parameters taken by the implementation callback are inferred automatically based on the declared interface. Thus, in the example above, the `value` will be of type `string` implicitly.

In your specs, you can now use the custom command as expected

*   End-to-End Test
*   Component Test

```
it('works', () => {  // from your cypress/e2e/spec.cy.ts  cy.visit('/')  // IntelliSense and TS compiler should  // not complain about unknown method  cy.dataCy('greeting')})
```

```
it('works', () => {  // from your src/components/MyComponent.cy.ts  cy.mount(<MyComponent />)  // IntelliSense and TS compiler should  // not complain about unknown method  cy.dataCy('greeting')})
```

#### Adding child or dual commands

When you add a custom command with `prevSubject`, Cypress will infer the subject type automatically based on the specified `prevSubject`.

```
// cypress/support/index.tsdeclare global {  namespace Cypress {    interface Chainable {      /**       * Custom command to type a few random words into input elements       * @param count=3       * @example cy.get('input').typeRandomWords()       */      typeRandomWords(        count?: number,        options?: Partial<TypeOptions>      ): Chainable<JQuery<HTMLElement>>    }  }}
```

```
// cypress/support/index.tsCypress.Commands.add(  'typeRandomWords',  { prevSubject: 'element' },  (subject /* :JQuery<HTMLElement> */, count = 3, options?) => {    return cy.wrap(subject).type(generateRandomWords(count), options)  })
```

#### Overwriting child or dual commands

When overwriting either built-in or custom commands which make use of `prevSubject`, you must specify generic parameters to help the type-checker to understand the type of the `prevSubject`.

```
interface TypeOptions extends Cypress.TypeOptions {  sensitive: boolean}Cypress.Commands.overwrite<'type', 'element'>(  'type',  (originalFn, element, text, options?: Partial<TypeOptions>) => {    if (options && options.sensitive) {      // turn off original log      options.log = false      // create our own log with masked message      Cypress.log({        $el: element,        name: 'type',        message: '*'.repeat(text.length),      })    }    return originalFn(element, text, options)  })
```

As you can see there are generic parameters `<'type', 'element'>` are used:

1.  The first parameter is the command name, equal to first parameter passed to `Cypress.Commands.overwrite`.
2.  The second parameter is the type of the `prevSubject` that is used by the original command. Possible values:
    *   'element' infers it as `JQuery<HTMLElement>`
    *   'window' infers it as `Window`
    *   'document' infers it as `Document`
    *   'optional' infers it as `unknown`

#### Examples:

*   See [Adding Custom Commands (TS)](https://github.com/cypress-io/cypress-example-recipes#fundamentals) example recipe.

### 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](/llm/markdown/app/references/recipes.md#Fundamentals) for instructions.

### Types for plugins

You can utilize Cypress's type declarations in your [plugins file](/llm/markdown/app/plugins/plugins-guide.md) by annotating it like the following:

```
// cypress/plugins/index.ts/** * @type {Cypress.PluginConfig} */module.exports = (on, config) => {}
```

### Using an External Typings File

You might find it easier to organize your types by moving them from the support file into an external [declaration (\*.d.ts) file](https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html). To do so, create a new file, like _cypress.d.ts_, and cut the types for your custom commands/assertions from the _support_ file and into the new file. Below is an example of moving the custom `cy.mount` typings that come by default with a component testing app into a root level _cypress.d.ts_ file.

*   cypress.d.ts

```
import { mount } from 'cypress/react'// Augment the Cypress namespace to include type definitions for// your custom command.// Alternatively, can be defined in cypress/support/component.d.ts// with a <reference path="./component" /> at the top of your spec.declare global {  namespace Cypress {    interface Chainable {      mount: typeof mount    }  }}
```

You might need to include the _\*.d.ts_ in the include options in any _tsconfig.json_ files in your project for TypeScript to pick up the new types:

*   tsconfig.json

```
"include": [  "src",  "./cypress.d.ts"]
```

*   ./cypress/tsconfig.json

```
"include": [  "**/*.ts",  "../cypress.d.ts"]
```

### Set up your dev environment

Please refer to your code editor in [TypeScript's Editor Support doc](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Editor-Support) and follow the instructions for your IDE to get TypeScript support and [intelligent code completion](/llm/markdown/app/tooling/IDE-integration.md#Intelligent-Code-Completion) configured in your developer environment before continuing. TypeScript support is built in for [Visual Studio Code](https://code.visualstudio.com/), [Visual Studio](https://www.visualstudio.com/), and [WebStorm](https://www.jetbrains.com/webstorm/) - all other editors require extra setup.

### Clashing types with Jest

If you are using both Jest and Cypress in the same project, the TypeScript types registered globally by the two test runners can clash. For example, both Jest and Cypress provide the clashing types for the `describe` and `it` functions. Both Jest and Expect (bundled inside Cypress) provide the clashing types for the `expect` assertion, etc.

You may want to consider configuring your app with separate `tsconfig.json` to solve [clashing types with jest](/llm/markdown/app/tooling/typescript-support.md#Clashing-types-with-Jest). You will need to exclude `cypress.config.ts`, `cypress`, `node_modules` in your root `tsconfig.json` file.

tsconfig.json

```
{  "exclude": ["cypress.config.ts", "cypress", "node_modules"]}
```

## History

| Version | Changes |
| --- | --- |
| [15.14.0](/llm/markdown/app/references/changelog.md#15-14-0) | Added support for TypeScript 6.0 |
| [15.0.0](/llm/markdown/app/references/changelog.md#15-0-0) | Raised minimum required TypeScript version from 4.0+ to 5.0+ and replaced `ts-node` with `tsx` to parse and run the `cypress.config.ts` file. |
| [13.0.0](/llm/markdown/app/references/changelog.md#13-0-0) | Raised minimum required TypeScript version from 3.4+ to 4.0+ |
| [10.0.0](/llm/markdown/app/references/changelog.md#10-0-0) | Update guide to cover TypeScript setup for component testing |
| [5.0.0](/llm/markdown/app/references/changelog.md#5-0-0) | Raised minimum required TypeScript version from 2.9+ to 3.4+ |
| [4.4.0](/llm/markdown/app/references/changelog.md#4-4-0) | Added support for TypeScript without needing your own transpilation through preprocessors. |

## See also

*   [IDE Integration](/llm/markdown/app/tooling/IDE-integration.md)
