使用jest的expect.extend(),TypeScript作用域为单个测试文件

rqqzpn5f  于 2023-04-03  发布在  Jest
关注(0)|答案(2)|浏览(160)

这个问题与Can you limit the scope of a TypeScript global type?类似,但有一点不同(尽管我也很想知道答案)。
在Jest中,我想做这样的事情:

declare global {
  namespace jest {
    interface Matchers<R> {
      toBeAwesome(this: Matchers<void, HTMLElement>): R;
    }
  }
}

export {};

expect.extend({
  toBeAwesome() {
    // ...
  }
});

然而,我只在那个特定的文件中调用extend,因此我不希望其他测试文件能够访问它。
我也尝试了一些hacky:

declare const expect: jest.Expect & {
  <T = any>(actual: T): jest.JestMatchers<T> & {
    toBeSelected(this: jest.Matchers<void, HTMLElement>): void;
  };
};

但方法根本不会出现。
我还尝试在全局范围之外直接声明namespace jest,但由于jest是一个全局名称空间,因此它创建了一个新的名称空间,而不是扩展另一个名称空间。
是否可以将增强的范围限定到特定文件和导入该文件的任何文件?

2sbarzqh

2sbarzqh1#

我不认为你可以在同一个包中限制一个扩展类型的作用域,但是你可以用你想要的类型定义你自己的expect函数:
比如:

function expectElement(actual: HTMLEelement): ElementExpect {
  return expect(actual) as any as ElementExpect
}

type ElementExpect = JestExpect & ElementMatchers

interface ElementMatchers<R = void> extends Matchers<void> {
  toBeSelected(): R
}

然后,可以说你的测试更明确:

it("should be awesome", () => {
  expectElement(el).toBeAwesome()
})
krcsximq

krcsximq2#

另一个解决方法是,如果您使用的是从@jest/globals显式导入(而不是@types/jest,它使全局变量在任何地方都可用于TS),则修改expect导入版本的类型。

import { expect as _expect } from '@jest/globals';

const expect = _expect as unknown as {
  <T = unknown>(actual: T): {
    toBeAwesome(): void;
  } & ReturnType<typeof _expect>;
} & typeof _expect;

正如所写的那样(可能有更好的方法),这并不为传递给expect()的实际内容提供类型验证,但它至少使匹配器可用并限于当前文件。
你也可以用全局类型(@types/jest)来实现这一点,方法是用不同的名称重新声明expect,例如const expectElement = expect as unknown as /* custom type */

相关问题