如何告诉编译器 .tsx 文件中的 window.Cypress?

How to tell the compiler about window.Cypress in .tsx files?

我正在使用 Cypress 和 TypeScript 构建应用程序。

我有以下代码,它会根据 Magic SDK 是否在 E2E 测试中运行而略微改变它的行为:

const magic = new Magic(window.ENV.MAGIC_PUBLISHABLE_KEY, {
  testMode: Boolean(window.Cypress),
});

TypeScript 抱怨 window.Cypress 并说:

Property 'Cypress' does not exist on type 'Window & typeof globalThis'.

如何将 Cypress 告诉 TypeScript?基本上我需要这样的东西:

type Window = {
  Cypress?: Cypress; // Where Cypress is the Cypress namespace
}

我在 Google 中找到了 this answer(以及其他),但我看不出这将如何解决这个具体问题。

编辑:

Tobias 在评论中链接的问题是不同的,因为如果你这样做:

declare global {
  Cypress: Cypress;
}

TypeScript 抱怨:

Unexpected labeled statement.

当你这样做时:

declare global {
  var Cypress: Cypress;
}

TypeScript 抱怨:

Cannot augment module 'Cypress' with value exports because it resolves to a non-module entity.

我在 Github 上找不到代码,但在我的 node_modules 中它位于此处:

因此,建议答案中的解决方案将不起作用,因为 Cypress 是一个名称空间,而不是一种类型 - 尽管要解决这个问题,您可能需要它是一种类型。

编辑 2:

Fody 的回答也不行。

Gleb Bahmutov 在他的幻灯片中使用的模式是

interface Window {
  Cypress? : any    // don't really need strict type here
}

if (window.Cypress) {   
  ...
}

将命名空间分配给声明的常量并将其导出:

declare global {
  export declare const Cypress: Cypress;
}

不能 100% 确定这是否有效,带有环境类型声明的东西总是有点挑剔。

经过一些尝试后,以下似乎有效:

declare global {
  interface Window {
    Cypress?: Cypress.Cypress;
  }
}

if (window.Cypress) {
  // ...
}