I am trying to add typescript definition to a jasmine matcher library.
I was able to add the matchers for the generic type T
but now i want to add matchers only to DOM elements.
Digging into the jasmine type definition code I found a similar approach to ArrayLike
(see here for the expect
overload and here for the ArrayLikeMatchers
).
So I created a similar one.
// 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;
}
}
But, is not working :(
Given the following code:
const div = document.createElement("div");
expect(div).toBeChecked();
The type checker is giving me the error:
[js] Property 'toBeChecked' does not exist on type 'Matchers'.
The only solution seems to be adding the expect
overload before the generic expect
(after the ArrayLike
overload here) in the core jasmine library.
But... it is not doable :)
Any hint on how to properly implement a working solution?
The problem is that Typescript chooses overloads in declaration order and the very generic
declare function expect<T>(actual: T): jasmine.Matchers<T>;
will come before your overload. You might be able to find some magic ordering using///
references but I have not been able to get it to work and it would be very brittle.A better approach would be to add your extra functions right on
Matchers<T>
but constrainthis
to be derived fromMatchers<HTMLElement>