15

Cypress documentation shows how to declare custom command types:

declare global {
  namespace Cypress {
    interface Chainable {
      /**
       * Custom command to select DOM element by data-cy attribute.
       * @example cy.dataCy('greeting')
       */
      dataCy(value: string): Chainable<Element>
    }
  }
}

But Typescript ESLint is unhappy about this due to "ES2015 module syntax is preferred over custom TypeScript modules and namespaces @typescript-eslint/no-namespace". Is it possible to rewrite this to import/export and if so, how? Or should I just disable the rule for this case?

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • So, do you think the docs are wrong? What happened when you tried removing the namespace? – user16695029 Apr 25 '22 at 09:30
  • I think the docs don't take this rule into account because it isn't part of TypeScript. If I removed the `namespace Cypress` line, I expect it would declare a new `Chainable` interface unrelated to `Cypress.Chainable` and so I couldn't call the method on a `Cypress.Chainable` value; or do you mean something else? (I can't try it right now, but can later if you think it's useful.) – Alexey Romanov Apr 25 '22 at 10:00
  • 2
    Are you trying with `allowDeclarations = true`, by default it's `false`. Also in a different way instead of putting this in global context , did you try creating a separate d.ts file with `declare module <> ` like syntax and then using directly in a .ts file: `///` – Navoneel Talukdar Apr 25 '22 at 10:55

1 Answers1

9

According to this, @typescript-eslint/no-namespace rule allows declare with custom TypeScript namespaces inside definition files.

So you may create a cypress.d.ts definition file and cut the types for your custom commands/assertions from the support file into this file:

// ./cypress.d.ts

declare namespace Cypress {
  interface Chainable {
    /**
     * Custom command to select DOM element by data-cy attribute.
     * @example cy.dataCy('greeting')
     */
    dataCy(value: string): Chainable<Element>
  }
}

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"
]

check this for more info.

Hafez Divandari
  • 8,381
  • 4
  • 46
  • 63