Jasmine 自定义匹配器类型定义
Jasmine custom matcher type definition
我正在尝试将 typescript 定义添加到 jasmine 匹配器 library。
我能够为泛型 T
添加匹配器,但现在我只想将匹配器添加到 DOM 元素。
深入研究 jasmine 类型定义代码,我发现了与 ArrayLike
类似的方法(请参阅 here for the expect
overload and here 了解 ArrayLikeMatchers
)。
所以我创建了一个类似的。
// Overload the expect
declare function expect<T extends HTMLElement>(actual: T): jasmine.DOMMatchers<T>;
declare namespace jasmine {
// Augment the standard matchers. This WORKS!
interface Matchers<T> {
toBeExtensible(): boolean;
toBeFrozen(): boolean;
toBeSealed(): boolean;
// ... other
}
// The matchers for DOM elements. This is NOT working!
interface DOMMatchers<T> extends Matchers<T> {
toBeChecked(): boolean;
toBeDisabled(): boolean;
}
}
但是,不起作用:(
给定以下代码:
const div = document.createElement("div");
expect(div).toBeChecked();
类型检查器给我错误:
[js] Property 'toBeChecked' does not exist on type 'Matchers'.
唯一的解决方案似乎是在 expect
通用 expect
之前添加 expect
重载 (在 ArrayLike
重载 here) 在核心 jasmine 库中。
但是...这是不可行的:)
关于如何正确实施有效解决方案的任何提示?
问题在于 Typescript 按声明顺序选择重载,而非常通用的 declare function expect<T>(actual: T): jasmine.Matchers<T>;
将出现在您的重载之前。您也许可以使用 ///
参考找到一些神奇的顺序,但我无法让它工作,而且它会非常脆弱。
更好的方法是在 Matchers<T>
上添加额外的函数,但将 this
限制为从 Matchers<HTMLElement>
派生
declare namespace jasmine {
interface Matchers<T> {
toBeExtensible(): boolean;
toBeFrozen(): boolean;
toBeSealed(): boolean;
// this must be derived from Matchers<HTMLElement>
toBeDisabled(this: Matchers<HTMLElement>): boolean;
// or make it generic, with T extending HTMLElement if you really need the actual type for some reason
toBeChecked<T extends HTMLElement>(this: Matchers<HTMLElement>): boolean;
}
}
// usage
const div = document.createElement("div");
expect(div).toBeChecked(); // ok
expect(10).toBeChecked() // error
我正在尝试将 typescript 定义添加到 jasmine 匹配器 library。
我能够为泛型 T
添加匹配器,但现在我只想将匹配器添加到 DOM 元素。
深入研究 jasmine 类型定义代码,我发现了与 ArrayLike
类似的方法(请参阅 here for the expect
overload and here 了解 ArrayLikeMatchers
)。
所以我创建了一个类似的。
// Overload the expect
declare function expect<T extends HTMLElement>(actual: T): jasmine.DOMMatchers<T>;
declare namespace jasmine {
// Augment the standard matchers. This WORKS!
interface Matchers<T> {
toBeExtensible(): boolean;
toBeFrozen(): boolean;
toBeSealed(): boolean;
// ... other
}
// The matchers for DOM elements. This is NOT working!
interface DOMMatchers<T> extends Matchers<T> {
toBeChecked(): boolean;
toBeDisabled(): boolean;
}
}
但是,不起作用:(
给定以下代码:
const div = document.createElement("div");
expect(div).toBeChecked();
类型检查器给我错误:
[js] Property 'toBeChecked' does not exist on type 'Matchers'.
唯一的解决方案似乎是在 expect
通用 expect
之前添加 expect
重载 (在 ArrayLike
重载 here) 在核心 jasmine 库中。
但是...这是不可行的:)
关于如何正确实施有效解决方案的任何提示?
问题在于 Typescript 按声明顺序选择重载,而非常通用的 declare function expect<T>(actual: T): jasmine.Matchers<T>;
将出现在您的重载之前。您也许可以使用 ///
参考找到一些神奇的顺序,但我无法让它工作,而且它会非常脆弱。
更好的方法是在 Matchers<T>
上添加额外的函数,但将 this
限制为从 Matchers<HTMLElement>
declare namespace jasmine {
interface Matchers<T> {
toBeExtensible(): boolean;
toBeFrozen(): boolean;
toBeSealed(): boolean;
// this must be derived from Matchers<HTMLElement>
toBeDisabled(this: Matchers<HTMLElement>): boolean;
// or make it generic, with T extending HTMLElement if you really need the actual type for some reason
toBeChecked<T extends HTMLElement>(this: Matchers<HTMLElement>): boolean;
}
}
// usage
const div = document.createElement("div");
expect(div).toBeChecked(); // ok
expect(10).toBeChecked() // error