4

I'm using cypress and declaring namespace to infer type of custom commands.

index.d.ts

declare namespace Cypress {
  interface Chainable {
    commandA: typeof commandA;
  }
}

commands.ts

const commandA = ...;

Cypress.commands.add('commandA', commandA);

In this context, I have to use CyHttpMessages type in cypress/types/net-stubbing package. So I imported that type in commands.ts file.

commands.ts (with import)

import { CyHttpMessages } from 'cypress/types/net-stubbing';

...

But, after importing that type index.d.ts file was broken with red lines. This file couldn't find type of commandA function. I think import statement is cause of this problem.

How can I use import statement with declare namespace ? What is the problem? Thanks for your reading.

2
  • I have this same issue 🤔 Make any progress in figuring it out? Commented Jan 19, 2022 at 19:39
  • Hi, could you please spin up a minimal reproducible example for me? I once had an issue similar to yours with playwright fixtures and I solved it through some wierdo magic. The project config was very specific though so I not sure if it would apply here without further context :). Commented Jan 20, 2022 at 15:30

2 Answers 2

1

You need to use the declare global {} when setting up the Typescript definition for custom Cypress commands.

The documentation provides an example but based on the provided information it should look like this:

index.d.ts

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

declare global {
  namespace Cypress {
    interface Chainable {
      commandA(): Chainable<Element>
    }
  }
}
Sign up to request clarification or add additional context in comments.

Comments

0

A solution with namespaces (not recommended) To resolve your issue, you can export your namespace:

// UtilBase.ts
import * as path from "path";
export namespace My.utils {
    export class UtilBase {
        protected fixPath(value: string): string {
            return value.replace('/', path.sep);
        }
   }
}

Then, you should be able to import it:

// UtilOne.ts
import {My} from './UtilBase';
namespace My.utils {
    export class UtilOne extends My.utils.UtilBase {
    }
}

However, if the purpose is to organize the code, it is a bad practice to use namespaces and (ES6) modules at the same time. With Node.js, your files are modules, then you should avoid namespaces.

Use ES6 modules without namespaces TypeScript supports the syntax of ES6 modules very well:

// UtilBase.ts
import * as path from "path";
export default class UtilBase {
    protected fixPath(value: string): string {
        return value.replace('/', path.sep);
    }
}

// UtilOne.ts
import UtilBase from './UtilBase';
export default class UtilOne extends UtilBase {
}

It is the recommended way. ES6 modules prevent naming conflicts with the ability to rename each imported resource.

Use a file tsconfig.json instead of /// <reference

// tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es6"
  },
  "exclude": [
    "node_modules"
  ]
}

This is from a different answer, here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.