如何在Playwright中使用泛型添加自定义匹配器?
Playwright 1.39+ 自定义泛型匹配器的实现问题与解决方案
自Playwright 1.39版本起,官方提供了支持TypeScript的自定义匹配器新创建方式,旧实现方法已被淘汰。
新方法示例
export const expect = base.extend({ toVerifySomething(something: any, predicate: (it: any) => boolean) { // ... }, });
新方法的问题
这种方式存在明显缺陷:由于使用了any类型,会丢失代码自动补全能力:
expect("some string").toVerifySomething((it) => it); // `(parameter) it: any`
泛型尝试失败
我尝试用泛型改写,但泛型T始终被推断为unknown:
export const expect = base.extend({ toVerifySomething<T>(something: T, predicate: (it: T) => boolean) { // ... }, }); expect("some string").toVerifySomething((it) => it); // `(parameter) it: unknown`
那么,能否在Playwright中使用泛型创建自定义匹配器?
查看expect的类型定义可以发现,它本身带有一个与actual类型匹配的泛型:
const expect: <string>(actual: string, messageOrOptions?: string | { message?: string }) => MakeMatchers<void, string, { toVerifySomething<T>(something: T, predicate: (it: T) => boolean): { message: () => string; pass: boolean; }; }>
旧方法扩展类型无效
我尝试沿用旧方法中的declare global扩展类型,但不适用于新结构:
export const expect = base.extend({ toVerifySomething(something: any, predicate: (it: any) => boolean) { // ... }, }); declare global { namespace PlaywrightTest { interface Matchers<R, T> { toVerifySomething(something: T, predicate: (it: T) => boolean): R; } } } expect("some string").toVerifySomething((it) => it); // `(parameter) it: unknown`
鼠标悬停在toVerifySomething上时,显示的类型信息如下:
(method) PlaywrightTest.Matchers<R, T = unknown>.toVerifySomething(something: string, predicate: (it: string) => boolean): void (+1 overload)
变通解决方案
编辑补充:我找到了一种结合旧方法的变通方案,可以恢复类型推断功能:
// 需要在`extend`后添加`<{}>` export const expect = base.extend<{}>({ toVerifySomething(something: any, predicate: (it: any) => boolean) { // ... }, }); declare global { namespace PlaywrightTest { interface Matchers<R, T> { toVerifySomething(something: T, predicate: (it: T) => boolean): R; } } } expect("some string").toVerifySomething((it) => it); // `(parameter) it: string`
该方案虽不完美,但足以满足日常需求。
内容的提问来源于stack exchange,提问作者David Guevara
相关产品推荐
相关产品推荐

