有没有办法让测试框架打字稿声明只在VS Code的测试文件中解析?

Nat*_*ley 6 type-declaration typescript visual-studio-code

此问题适用于以下每个源文件组织策略:

测试完全分开

/src
/tests
Run Code Online (Sandbox Code Playgroud)

每个功能测试

/src/feature/
/src/feature/__tests__
Run Code Online (Sandbox Code Playgroud)

每个文件测试

/src/feature/foo.ts
/src/feature/foo.test.ts
Run Code Online (Sandbox Code Playgroud)

安装@mocha/types使这些仅测试声明在整个代码库中可用作有效标识符.更新tsconfig.json并指定"types": []将其排除是很容易的,但是当您在一个文件中手动引用它时,无论是通过import 'mocha'还是/// <reference types="mocha" />突然它再次感染整个代码库.

有没有办法让类型声明只对单元测试有效在测试文件中正确解析并在其他源文件中显示为无效?

请注意,我在这里使用VS Code.当然,我可以有一个单独的tsconfig文件用于外部构建设置,例如via gulp或者其他什么,但是我正在编辑VS Code中的实际代码,而红色的波浪线和"问题"似乎无法解析.要么我在整个代码库中接受单元测试标识符的无效自动完成,要么我的单元测试显示模块解析错误.

Mei*_*hes 1

这不是一件容易的事……这是我想出的最好的办法。你不会喜欢它,但它确实有效:

创建一个文件mocha.ts,您需要在其中重新导出运行时可用的全局变量并(您不喜欢的部分)重新定义它们的类型 - 尽可能多地进行:

declare var global: any;

export const describe = global.describe as (msg: string, cb: () => void) => void;
export const it = global.it as (msg: string, cb: () => void) => void;
Run Code Online (Sandbox Code Playgroud)

现在,只需导入describe即可it离开./mocha。不会污染全局命名空间。

在此输入图像描述

类型的重新定义很糟糕;但您可以简单地从明确键入的内容中选择要使用的相关部分。我认为您无法直接导入类型并且不会产生全局变量,因为它的类型是这样的

我查看的其他内容是利用 mocha“require”,因为文档暗示您可以describe像这样抓取:require('mocha').describe...我尝试了这个(使用 mocha cli 运行)但无法让它工作。请参阅: http: //mochajs.org/#require不过...我认为无论如何您都会受到全局类型的影响。

附录

复制输入内容的完整 mocha.ts:

declare var global: any;

export const describe = global.describe as IContextDefinition;
export const it = global.it as ITestDefinition;

// following is from DefinitelyTyped

interface IContextDefinition {
  (description: string, callback: (this: ISuiteCallbackContext) => void): ISuite;
  only(description: string, callback: (this: ISuiteCallbackContext) => void): ISuite;
  skip(description: string, callback: (this: ISuiteCallbackContext) => void): void;
  timeout(ms: number): void;
}

interface ISuiteCallbackContext {
  timeout(ms: number): this;
  retries(n: number): this;
  slow(ms: number): this;
}

interface ISuite {
  parent: ISuite;
  title: string;

  fullTitle(): string;
}

interface ITestDefinition {
  (expectation: string, callback?: (this: ITestCallbackContext, done: MochaDone) => any): ITest;
  only(expectation: string, callback?: (this: ITestCallbackContext, done: MochaDone) => any): ITest;
  skip(expectation: string, callback?: (this: ITestCallbackContext, done: MochaDone) => any): void;
  timeout(ms: number): void;
  state: "failed" | "passed";
}
interface ITestCallbackContext {
  skip(): this;
  timeout(ms: number): this;
  retries(n: number): this;
  slow(ms: number): this;
  [index: string]: any;
}

interface MochaDone {
  (error?: any): any;
}

interface ITest extends IRunnable {
  parent: ISuite;
  pending: boolean;
  state: 'failed' | 'passed' | undefined;

  fullTitle(): string;
}

interface IRunnable {
  title: string;
  fn: Function;
  async: boolean;
  sync: boolean;
  timedOut: boolean;
  timeout(n: number): this;
}
Run Code Online (Sandbox Code Playgroud)